Company Intelligence

Monitor target accounts and customer companies for growth signals, risks, and expansion opportunities.

Why Monitor Company Changes?

  • Expansion signals - Growing headcount indicates budget and new initiatives
  • Risk detection - Identify churn risks from layoffs or leadership changes
  • Competitive intelligence - Track competitor movements and strategies
  • Account mapping - Discover new stakeholders as they join

What You'll Learn

In this tutorial, you'll learn how to:

  • Set up company monitoring for accounts
  • Track growth and contraction signals
  • Monitor leadership and department changes
  • Build automated account intelligence reports
  • Integrate company data with your CRM

Company Event Types

Sales Webhooks monitors these company-related events:

Event Description Business Impact
company.employee_count_changed Significant headcount change Growth/contraction indicator
company.description_changed Company description updated Strategy or focus shift
company.post_created Company announcement News, product launches

Implementation Guide

Step 1: Set Up Company Monitoring

Create subscriptions for your target accounts and customer companies:

// Import accounts from your CRM
const accounts = await crm.accounts.list({
  filters: {
    status: ['customer', 'prospect', 'target'],
    tier: ['enterprise', 'mid-market']
  }
});

// Create company subscriptions
const subscriptions = [];
for (const account of accounts) {
  if (account.linkedin_url) {
    const subscription = await client.subscriptions.create({
      entity_type: 'company',
      linkedin_url: account.linkedin_url
    });
    
    subscriptions.push({
      subscription_id: subscription.id,
      account_id: account.id,
      company_name: account.name,
      account_status: account.status
    });
  }
}

// Store mapping for reference
await db.company_subscriptions.bulkInsert(subscriptions);

Step 2: Process Company Intelligence

Handle company change events and extract insights:

app.post('/company-webhook', async (req, res) => {
  const event = req.body;
  
  // Get account context
  const account = await getAccountByLinkedIn(
    event.data.entity.linkedin_url
  );
  
  switch (event.type) {
    case 'company.employee_count_changed':
      await handleHeadcountChange(event.data, account);
      break;
    case 'company.description_changed':
      await handleStrategyChange(event.data, account);
      break;
    case 'company.post_created':
      await handleCompanyNews(event.data, account);
      break;
  }
  
  res.status(200).send('OK');
});

async function handleHeadcountChange(data, account) {
  const change = data.changes;
  const growthRate = calculateGrowthRate(
    change.previous_employee_count,
    change.current_employee_count
  );
  
  // Store intelligence
  const intelligence = {
    account_id: account.id,
    type: 'headcount_change',
    previous_value: change.previous_employee_count,
    current_value: change.current_employee_count,
    growth_rate: growthRate,
    change_date: new Date(),
    insights: generateHeadcountInsights(change, growthRate)
  };
  
  await db.company_intelligence.insert(intelligence);
  
  // Trigger appropriate workflows
  if (growthRate > 0.1) { // 10%+ growth
    await triggerExpansionOpportunity(account, intelligence);
  } else if (growthRate < -0.1) { // 10%+ contraction
    await triggerRiskAlert(account, intelligence);
  }
}

function generateHeadcountInsights(change, growthRate) {
  const insights = [];
  
  if (growthRate > 0.2) {
    insights.push('Rapid expansion - potential new initiatives');
    insights.push('Budget likely increasing');
    insights.push('Good time for upsell conversations');
  } else if (growthRate > 0.1) {
    insights.push('Steady growth - healthy business');
    insights.push('May need to scale existing solutions');
  } else if (growthRate < -0.15) {
    insights.push('Significant downsizing detected');
    insights.push('Review contract and payment terms');
    insights.push('Churn risk - schedule check-in');
  }
  
  // Department-specific insights
  if (change.department_changes) {
    for (const [dept, change] of Object.entries(change.department_changes)) {
      if (change > 0) {
        insights.push(`${dept} team growing - potential opportunity`);
      }
    }
  }
  
  return insights;
}

Step 3: Build Intelligence Dashboard

Create a comprehensive view of account intelligence:

// Account intelligence API
app.get('/api/account-intelligence/:accountId', async (req, res) => {
  const accountId = req.params.accountId;
  
  // Get all intelligence for account
  const intelligence = await db.query(`
    SELECT 
      ci.*,
      cs.linkedin_url,
      cs.company_name
    FROM company_intelligence ci
    JOIN company_subscriptions cs ON cs.account_id = ci.account_id
    WHERE ci.account_id = $1
    ORDER BY ci.created_at DESC
  `, [accountId]);
  
  // Get growth metrics
  const growthMetrics = await calculateGrowthMetrics(accountId);
  
  // Get risk indicators
  const riskScore = await calculateRiskScore(accountId);
  
  // Get opportunity indicators
  const opportunityScore = await calculateOpportunityScore(accountId);
  
  res.json({
    account_id: accountId,
    intelligence_events: intelligence,
    metrics: {
      growth: growthMetrics,
      risk_score: riskScore,
      opportunity_score: opportunityScore,
      last_updated: new Date()
    },
    recommendations: generateRecommendations(
      intelligence,
      growthMetrics,
      riskScore,
      opportunityScore
    )
  });
});

async function calculateGrowthMetrics(accountId) {
  const sixMonthsAgo = new Date();
  sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
  
  const data = await db.query(`
    SELECT 
      type,
      previous_value,
      current_value,
      created_at
    FROM company_intelligence
    WHERE account_id = $1
    AND type = 'headcount_change'
    AND created_at > $2
    ORDER BY created_at
  `, [accountId, sixMonthsAgo]);
  
  if (data.length === 0) return null;
  
  const firstCount = data[0].previous_value;
  const lastCount = data[data.length - 1].current_value;
  
  return {
    six_month_growth_rate: ((lastCount - firstCount) / firstCount) * 100,
    current_headcount: lastCount,
    growth_trajectory: calculateTrajectory(data),
    department_changes: await getDepartmentChanges(accountId)
  };
}

Step 4: Automated Intelligence Reports

Generate weekly account intelligence summaries:

// Weekly intelligence report generator
async function generateWeeklyIntelligenceReport() {
  const accounts = await getMonitoredAccounts();
  
  for (const account of accounts) {
    const intelligence = await gatherWeeklyIntelligence(account.id);
    
    if (intelligence.hasSignificantChanges) {
      const report = {
        account_name: account.name,
        account_owner: account.owner_email,
        summary: intelligence.summary,
        key_changes: intelligence.changes,
        risk_indicators: intelligence.risks,
        opportunities: intelligence.opportunities,
        recommended_actions: intelligence.actions
      };
      
      // Send to account owner
      await sendIntelligenceEmail(report);
      
      // Update CRM
      await updateCRMIntelligence(account.id, report);
      
      // Create tasks if needed
      if (report.risk_indicators.length > 0) {
        await createCRMTask({
          account_id: account.id,
          type: 'risk_mitigation',
          priority: 'high',
          description: `Review account health: ${report.risk_indicators.join(', ')}`,
          due_date: getBusinessDaysFromNow(3)
        });
      }
    }
  }
}

async function gatherWeeklyIntelligence(accountId) {
  const oneWeekAgo = new Date();
  oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
  
  // Get all changes
  const changes = await db.company_intelligence.findAll({
    where: {
      account_id: accountId,
      created_at: { $gt: oneWeekAgo }
    }
  });
  
  // Analyze patterns
  const analysis = {
    hasSignificantChanges: changes.length > 0,
    changes: [],
    risks: [],
    opportunities: [],
    actions: [],
    summary: ''
  };
  
  for (const change of changes) {
    if (change.type === 'headcount_change') {
      if (change.growth_rate < -0.1) {
        analysis.risks.push('Headcount reduction detected');
        analysis.actions.push('Schedule executive check-in');
      } else if (change.growth_rate > 0.15) {
        analysis.opportunities.push('Rapid growth phase');
        analysis.actions.push('Propose expansion package');
      }
    }
    
    if (change.type === 'leadership_change') {
      analysis.changes.push(`New ${change.position}: ${change.name}`);
      analysis.actions.push('Introduce to new stakeholder');
    }
  }
  
  analysis.summary = generateSummary(analysis);
  return analysis;
}

Step 5: Competitive Intelligence

Monitor competitors for strategic insights:

// Competitor monitoring setup
const competitors = [
  { name: 'Competitor A', linkedin_url: 'https://linkedin.com/company/competitor-a' },
  { name: 'Competitor B', linkedin_url: 'https://linkedin.com/company/competitor-b' }
];

for (const competitor of competitors) {
  await client.subscriptions.create({
    entity_type: 'company',
    linkedin_url: competitor.linkedin_url
  });
}

// Process competitor intelligence
async function handleCompetitorIntelligence(event) {
  const competitor = identifyCompetitor(event.data.entity.linkedin_url);
  
  if (event.type === 'company.post_created') {
    // Analyze for product announcements, partnerships
    const analysis = await analyzeCompetitorContent(event.data.post);
    
    if (analysis.is_product_announcement) {
      await notifyProductTeam({
        competitor: competitor.name,
        announcement: analysis.summary,
        features: analysis.extracted_features,
        market_impact: analysis.impact_assessment
      });
    }
    
    if (analysis.is_partnership) {
      await notifySalesTeam({
        competitor: competitor.name,
        partner: analysis.partner_name,
        deal_type: analysis.partnership_type,
        affected_accounts: await findAffectedAccounts(analysis)
      });
    }
  }
  
  if (event.type === 'company.employee_count_changed') {
    await trackCompetitorGrowth({
      competitor: competitor.name,
      previous_size: event.data.changes.previous_employee_count,
      current_size: event.data.changes.current_employee_count,
      growth_rate: event.data.growth_rate,
      market_share_impact: calculateMarketImpact(event.data)
    });
  }
}

Advanced Intelligence Features

🔍 Pro Intelligence Tips

  • Cross-reference data - Combine with contact changes for full picture
  • Set smart alerts - Focus on actionable changes, not noise
  • Track patterns - Look for trends over time, not just snapshots
  • Automate responses - Build playbooks for common scenarios

Account Health Scoring

function calculateAccountHealth(intelligence) {
  let healthScore = 100;
  const factors = [];
  
  // Headcount trends (-30 to +20 points)
  const headcountTrend = intelligence.growth_metrics.growth_trajectory;
  if (headcountTrend < -0.1) {
    healthScore -= 30;
    factors.push({ factor: 'Declining headcount', impact: -30 });
  } else if (headcountTrend > 0.1) {
    healthScore += 20;
    factors.push({ factor: 'Growing headcount', impact: +20 });
  }
  
  // Leadership stability (-20 to 0 points)
  const leadershipChanges = intelligence.leadership_changes_6m;
  if (leadershipChanges > 2) {
    healthScore -= 20;
    factors.push({ factor: 'Leadership instability', impact: -20 });
  }
  
  // Engagement level (0 to +15 points)
  const engagementScore = intelligence.content_engagement_score;
  if (engagementScore > 80) {
    healthScore += 15;
    factors.push({ factor: 'High engagement', impact: +15 });
  }
  
  // Strategic alignment (0 to +15 points)
  if (intelligence.strategic_initiatives.includes('digital_transformation')) {
    healthScore += 15;
    factors.push({ factor: 'Strategic alignment', impact: +15 });
  }
  
  return {
    score: Math.max(0, Math.min(100, healthScore)),
    factors: factors,
    recommendation: getHealthRecommendation(healthScore)
  };
}

Salesforce Integration

async function syncToSalesforce(intelligence) {
  const sf = await salesforce.login();
  
  // Update account record
  await sf.sobject('Account').update({
    Id: intelligence.salesforce_id,
    LinkedInEmployeeCount__c: intelligence.current_headcount,
    LinkedInGrowthRate__c: intelligence.growth_rate,
    AccountHealthScore__c: intelligence.health_score,
    LastIntelligenceUpdate__c: new Date(),
    IntelligenceSummary__c: intelligence.summary
  });
  
  // Create intelligence record
  await sf.sobject('AccountIntelligence__c').create({
    Account__c: intelligence.salesforce_id,
    Type__c: intelligence.type,
    Details__c: JSON.stringify(intelligence.details),
    BusinessImpact__c: intelligence.impact,
    RecommendedAction__c: intelligence.recommended_action,
    AlertSent__c: intelligence.alert_sent
  });
  
  // Create task if action needed
  if (intelligence.requires_action) {
    await sf.sobject('Task').create({
      WhatId: intelligence.salesforce_id,
      Subject: `Action Required: ${intelligence.action_summary}`,
      Description: intelligence.action_details,
      Priority: intelligence.priority,
      ActivityDate: intelligence.due_date,
      OwnerId: intelligence.account_owner_id
    });
  }
}

Next Steps

With company intelligence in place, consider:

Ready to monitor companies?

Start tracking your accounts for growth signals and risks with real-time LinkedIn intelligence.

Set Up Company Monitoring →