Your lead scoring model probably looks at form fills, page views, and email opens. But what if you could score leads based on what their company is doing right now? A lead from a company that just raised $20M, opened a new office, and is hiring 15 engineers should score differently than a lead from a company in a hiring freeze. By integrating a company signals API into your lead scoring pipeline, you can move from guesswork to precision — and prioritize the leads that are actually ready to buy.
In this guide, we'll walk through a complete signal-based lead scoring framework: the scoring model, the code, and the webhook integration. Whether you're building real-time company signals for developers into an existing CRM or creating a custom lead scoring API from scratch, you'll leave with a working implementation you can deploy today.
Why Traditional Lead Scoring Is Incomplete
Most lead scoring systems operate on a single dimension: individual behavior. They track what a person does — clicks an email, downloads a whitepaper, visits the pricing page — and assign points accordingly. This approach has been the standard for over a decade, and it works. To a point.
The problem is that behavioral data only tells you about the individual's interest level. It tells you nothing about the company's buying capacity, timing, or urgency. Consider two leads with identical behavioral scores:
- Lead A: Marketing manager at a company that just announced layoffs and lost its VP of Sales.
- Lead B: Marketing manager at a company that just closed a $15M Series B and is hiring across three departments.
Both leads filled out your demo form. Both visited your pricing page twice. A traditional scoring model treats them identically. But any experienced sales rep will tell you that Lead B is worth 10x more attention right now.
According to Gartner's research on B2B sales technology, companies that incorporate firmographic and intent data into their scoring models see 35% higher conversion rates from MQL to SQL. The missing ingredient isn't more behavioral data — it's company-level context.
The best lead scoring combines both dimensions:
- Behavioral signals — what the individual is doing (page visits, form fills, email engagement)
- Company signals — what the organization is doing (funding, hiring, expansion, risk events)
When you layer company signals on top of behavioral scoring, you stop treating all leads as equal and start treating them as contextual. This is the foundation of signal-based selling.
What Are Company Signals?
Company signals are real-time events that indicate changes in a company's trajectory, priorities, or capacity to buy. Think of them as the business equivalent of vital signs — they tell you whether a company is healthy, growing, contracting, or pivoting.
A modern signal intelligence API like BounceWatch tracks 40+ real-time event types, including:
- Growth signals: funding rounds, hiring surges, geographic expansion, new product launches
- People signals: key executive hires, leadership changes, board appointments
- Strategic signals: Partnerships, acquisitions, pivots, market entries
- Risk signals: layoffs, shutdown risk indicators, key departures, litigation
Each signal in the BounceWatch API includes structured metadata:
- Type: The signal category (e.g.,
funding_round,hiring_surge,layoffs) - Confidence score: How certain we are about this signal (0.0 to 1.0)
- Timestamp: When the event was detected
- Description: Human-readable summary of the event
- Source: Where the signal was sourced from
This structured format is what makes signals programmable. You don't need a human to interpret a news article — you get machine-readable events that slot directly into your scoring logic.
Signal-Based Lead Scoring Model
Before writing any code, you need a scoring framework. Below is a battle-tested model that maps company signals to point values. These values are starting points — you should tune them based on your sales cycle, deal size, and industry.
Positive Signals (Increase Score)
These signals indicate a company is growing, investing, and likely in a position to buy:
- Recently Funded (+30 points) — A company that just closed a funding round has fresh capital and a mandate to grow. They're actively looking for tools and services to deploy that capital. Funding signals are one of the strongest buying indicators in B2B sales.
- Hiring Surge (+20 points) — When a company is hiring aggressively (especially in your target department), it means they're scaling. Scaling teams need new tools. A hiring surge of 10+ roles in 30 days is a particularly strong signal.
- Expansion Announced (+25 points) — New offices, new markets, new geographies. Expansion signals indicate that a company is entering a phase where they need infrastructure, services, and vendor relationships in unfamiliar territory.
- New Product Launch (+15 points) — Companies launching new products are investing in growth. They're likely evaluating supporting tools and have active project budgets.
- Key Hire in Relevant Role (+20 points) — A new VP of Engineering, Head of Marketing, or CRO often comes with a mandate to evaluate and replace existing tools. Key hire signals are especially valuable when the hire matches your buyer persona.
- Partnership Announced (+10 points) — Partnerships signal an expanding ecosystem. The company is investing in integrations and may need complementary tools.
Negative/Risk Signals (Decrease Score)
These signals indicate a company may be contracting, distracted, or otherwise unlikely to buy:
- Layoffs Announced (-25 points) — Layoff signals typically mean budget cuts, hiring freezes, and tool consolidation. Your sales cycle will be longer and harder.
- Shutdown Risk (-40 points) — If a company is showing shutdown risk indicators, don't invest sales time. This is the strongest negative signal available.
- Key Exit (-15 points) — When your champion or the decision-maker leaves the company, the deal dynamics change entirely. You may need to restart the relationship with their replacement.
- Pivot Announced (-10 points) — A company mid-pivot has shifting priorities. The problem you solve may no longer be on their radar, or the team structure may be reorganizing.
Signal Velocity Multiplier
Individual signals are useful. But the velocity of signals — how many occur in a short time window — is often even more telling.
Signal velocity is the rate at which positive company signals accumulate over a defined time window. A company with 3+ positive signals in 30 days is in an active growth phase and should be prioritized above companies with a single signal.
Here's the multiplier logic:
- 1 positive signal in 30 days: 1.0x (no multiplier)
- 2 positive signals in 30 days: 1.2x multiplier
- 3+ positive signals in 30 days: 1.5x multiplier
For example, a company that received funding (+30), announced expansion (+25), and posted a hiring surge (+20) all within the last month generates a raw signal score of 75. With the 1.5x velocity multiplier, that becomes 112.5 points — a screaming hot lead by any measure.
Signal velocity works because it captures momentum. A single funding round is interesting. A funding round combined with aggressive hiring and geographic expansion tells you the company is in full-scale growth mode and actively deploying capital.
Implementing Signal-Based Lead Scoring with the BounceWatch API
Now let's build this. We'll use Python for the examples, but the concepts apply to any language. The BounceWatch API returns standard JSON, so you can integrate it with Node.js, Go, Ruby, or whatever your stack uses.
Step 1: Fetch Company Signals via API
The core endpoint for signal retrieval is:
GET /api/v1/company/{domain}?enrich=signals
This returns the company profile enriched with recent signals. Here's a sample response:
{
"domain": "acmecorp.com",
"name": "Acme Corp",
"industry": "SaaS",
"employee_count": 250,
"signals": [
{
"type": "funding_round",
"title": "Acme Corp raises $20M Series B",
"description": "Acme Corp closed a $20M Series B led by Sequoia Capital to expand its AI-powered analytics platform.",
"confidence": 0.95,
"detected_at": "2026-03-15T08:30:00Z",
"source": "press_release"
},
{
"type": "hiring_surge",
"title": "Acme Corp hiring 18 engineering roles",
"description": "Acme Corp posted 18 new engineering positions in the last 14 days, indicating rapid team scaling.",
"confidence": 0.88,
"detected_at": "2026-03-18T12:00:00Z",
"source": "job_boards"
},
{
"type": "key_hire",
"title": "New VP of Sales joins Acme Corp",
"description": "Jane Smith joined Acme Corp as VP of Sales, previously held the same role at Datadog.",
"confidence": 0.92,
"detected_at": "2026-03-10T09:15:00Z",
"source": "linkedin"
}
],
"signal_summary": {
"total_signals_30d": 3,
"positive_signals": 3,
"negative_signals": 0,
"signal_velocity": "high"
}
}
Here's the Python code to fetch signals for a domain:
import requests
BOUNCEWATCH_API_KEY = "your_api_key_here"
BASE_URL = "https://api.bouncewatch.com/api/v1"
def get_company_signals(domain: str) -> dict:
"""Fetch company profile with signals from BounceWatch API."""
response = requests.get(
f"{BASE_URL}/company/{domain}",
params={"enrich": "signals"},
headers={"Authorization": f"Bearer {BOUNCEWATCH_API_KEY}"}
)
response.raise_for_status()
return response.json()
# Example usage
company = get_company_signals("acmecorp.com")
print(f"Company: {company['name']}")
print(f"Signals detected: {company['signal_summary']['total_signals_30d']}")
for signal in company["signals"]:
print(f" - [{signal['type']}] {signal['title']} (confidence: {signal['confidence']})")
Step 2: Map Signals to Scores
Next, define your scoring dictionary and build a function that calculates the total signal score:
from datetime import datetime, timedelta, timezone
# Signal type to point value mapping
SIGNAL_SCORES = {
# Positive signals
"funding_round": 30,
"hiring_surge": 20,
"expansion": 25,
"new_product_launch": 15,
"key_hire": 20,
"partnership": 10,
# Negative signals
"layoffs": -25,
"shutdown_risk": -40,
"key_exit": -15,
"pivot": -10,
}
# Minimum confidence threshold to count a signal
MIN_CONFIDENCE = 0.7
def calculate_signal_score(signals: list) -> dict:
"""Calculate total signal score with velocity multiplier."""
now = datetime.now(timezone.utc)
thirty_days_ago = now - timedelta(days=30)
raw_score = 0
positive_count = 0
for signal in signals:
# Skip low-confidence signals
if signal["confidence"] < MIN_CONFIDENCE:
continue
signal_type = signal["type"]
points = SIGNAL_SCORES.get(signal_type, 0)
# Apply signal decay: signals older than 30 days get half points
detected_at = datetime.fromisoformat(signal["detected_at"].replace("Z", "+00:00"))
if detected_at < thirty_days_ago:
points = points * 0.5
raw_score += points
if points > 0:
positive_count += 1
# Apply velocity multiplier
if positive_count >= 3:
multiplier = 1.5
elif positive_count >= 2:
multiplier = 1.2
else:
multiplier = 1.0
final_score = raw_score * multiplier
return {
"raw_score": raw_score,
"velocity_multiplier": multiplier,
"final_score": round(final_score, 1),
"positive_signals": positive_count,
"signal_velocity": "high" if positive_count >= 3 else "medium" if positive_count >= 2 else "low"
}
This function handles three important concerns: confidence filtering (ignoring low-quality signals), signal decay (reducing the value of older signals), and velocity multipliers (rewarding signal momentum).
Step 3: Combine with Behavioral Score
Now merge the signal score with your existing behavioral lead score. The key decision here is weighting — how much influence should company signals have relative to individual behavior?
def calculate_combined_score(
behavioral_score: float,
signal_score: float,
behavioral_weight: float = 0.4,
signal_weight: float = 0.6
) -> dict:
"""
Combine behavioral and signal scores with configurable weighting.
Default: 40% behavioral + 60% signal.
Signal-heavy weighting works best for high-ACV B2B sales.
For product-led growth, consider 60/40 behavioral/signal.
"""
# Normalize scores to 0-100 range
normalized_behavioral = min(behavioral_score, 100)
normalized_signal = min(max(signal_score, -50), 150) # Allow negatives, cap at 150
combined = (normalized_behavioral * behavioral_weight) + (normalized_signal * signal_weight)
return {
"behavioral_score": normalized_behavioral,
"signal_score": normalized_signal,
"combined_score": round(combined, 1),
"behavioral_weight": behavioral_weight,
"signal_weight": signal_weight
}
# Example
result = calculate_combined_score(
behavioral_score=25, # Low-moderate behavioral engagement
signal_score=112.5 # High signal score (3 positive signals with velocity)
)
print(f"Combined score: {result['combined_score']}")
# Output: Combined score: 77.5 (25*0.4 + 112.5*0.6 = 10 + 67.5)
We recommend a 60/40 signal-to-behavioral weighting for enterprise and mid-market B2B sales, where deal timing is heavily influenced by company-level events. For product-led growth motions where individual engagement is a stronger buying signal, consider flipping this to 60/40 behavioral-to-signal. As HubSpot's lead scoring methodology emphasizes, the best weighting depends on your specific sales motion and deal cycle.
Step 4: Automate with Webhooks
Polling the API for every lead on a schedule works, but it's inefficient. The better approach is webhooks: BounceWatch pushes new signals to your endpoint in real-time, and you update lead scores instantly.
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/webhooks/bouncewatch/signals", methods=["POST"])
def handle_signal_webhook():
"""
Receive real-time signal events from BounceWatch.
Automatically recalculate and update lead scores.
"""
payload = request.json
# Verify webhook signature (always do this in production)
signature = request.headers.get("X-BounceWatch-Signature")
if not verify_webhook_signature(payload, signature):
return jsonify({"error": "Invalid signature"}), 401
domain = payload["domain"]
new_signal = payload["signal"]
print(f"New signal for {domain}: {new_signal['type']} - {new_signal['title']}")
# 1. Look up all leads associated with this domain
leads = get_leads_by_company_domain(domain)
# 2. Fetch full signal history for recalculation
company = get_company_signals(domain)
# 3. Recalculate signal score
signal_result = calculate_signal_score(company["signals"])
# 4. Update each lead's combined score
for lead in leads:
combined = calculate_combined_score(
behavioral_score=lead["behavioral_score"],
signal_score=signal_result["final_score"]
)
update_lead_score(lead["id"], combined["combined_score"])
# 5. Check if lead crossed a threshold and needs routing
route_lead_by_score(lead["id"], combined["combined_score"])
return jsonify({"status": "processed", "leads_updated": len(leads)}), 200
With webhooks, your lead scores update within seconds of a signal being detected. A company announces funding at 9 AM, and by 9:01 AM your SDR team sees updated scores in their CRM. This is what real-time lead scoring actually looks like.
Step 5: Route High-Score Leads
The final piece is automated routing. Once you have combined scores, define thresholds that trigger different actions:
def route_lead_by_score(lead_id: str, combined_score: float):
"""Route leads based on combined score thresholds."""
if combined_score >= 80:
# HOT LEAD: Immediate SDR outreach
assign_to_sdr(lead_id, priority="urgent")
send_slack_notification(
channel="#hot-leads",
message=f"Lead {lead_id} scored {combined_score} - immediate outreach needed"
)
create_task_in_crm(lead_id, action="call", due="today")
elif combined_score >= 50:
# WARM LEAD: Accelerated nurture sequence
enroll_in_sequence(lead_id, sequence="warm-signal-nurture")
assign_to_sdr(lead_id, priority="normal")
elif combined_score >= 25:
# COOL LEAD: Standard marketing nurture
enroll_in_sequence(lead_id, sequence="standard-nurture")
else:
# LOW PRIORITY: Keep in marketing funnel
tag_lead(lead_id, tags=["low-priority", "monitor"])
# Score threshold reference:
# 80+ -> Immediate SDR outreach (call today)
# 50-79 -> Accelerated nurture + SDR assignment
# 25-49 -> Standard marketing nurture sequence
# <25 -> Monitor, keep in marketing funnel
The beauty of this system is that it's self-updating. A lead that was scored at 30 yesterday can jump to 85 today if their company announces a major funding round. Your SDR team gets notified immediately, and the lead is routed before the competitor even knows what happened.
Before and After: Lead Scoring Without vs With Signals
Let's make this concrete with a real scenario. Imagine a lead named Alex, a product manager at a mid-market SaaS company:
| Scoring Factor | Without Signals | With Signals |
|---|---|---|
| Form fill (demo request) | +10 pts | +10 pts |
| Pricing page visits (x2) | +5 pts | +5 pts |
| Email open | +3 pts | +3 pts |
| Recently Funded ($20M Series B) | — | +30 pts |
| Hiring Surge (18 roles) | — | +20 pts |
| Key Hire (new VP Sales) | — | +20 pts |
| Velocity Multiplier (3+ signals) | — | 1.5x on signal score |
| Behavioral Score | 18 pts | 18 pts |
| Signal Score | 0 pts | 105 pts (70 x 1.5) |
| Combined Score | 18 pts → Low priority | 70.2 pts → High priority! |
| Action Taken | Sits in nurture for weeks | SDR assigned, outreach within 24h |
Without signals, Alex is a low-priority lead who sits in an email nurture sequence for weeks. With signals, Alex's company context reveals that this is a high-priority opportunity — a recently funded, rapidly growing company with a new decision-maker coming in. The SDR team reaches out immediately, before competitors catch on.
This is the difference between signal-based outbound and spray-and-pray prospecting.
Advanced Patterns
Once your basic signal scoring is working, here are three advanced patterns that top-performing teams implement:
Compound Signals
Some signal combinations are worth more than the sum of their parts. Funding + hiring surge is a strong indicator. But funding + hiring surge + key hire in your buyer persona's role is an almost certain buying window. Define compound rules that add bonus points for specific combinations:
COMPOUND_BONUSES = {
("funding_round", "hiring_surge"): 15, # Growth mode
("funding_round", "expansion"): 20, # Aggressive scaling
("key_hire", "hiring_surge"): 10, # New leader building team
("funding_round", "hiring_surge", "key_hire"): 30 # Triple threat
}
def apply_compound_bonuses(signal_types: set) -> int:
bonus = 0
for combo, points in COMPOUND_BONUSES.items():
if set(combo).issubset(signal_types):
bonus += points
return bonus
Signal Decay
A funding round from last week is hot news. A funding round from six months ago is old context. Implement time-based decay to ensure your scores reflect current reality:
- 0-7 days: 100% of point value
- 8-30 days: 80% of point value
- 31-60 days: 50% of point value
- 61-90 days: 25% of point value
- 90+ days: 10% of point value (or exclude entirely)
This prevents stale signals from inflating scores. A company that raised funding 8 months ago has likely already deployed that capital and made their vendor decisions.
Industry-Specific Weighting
Not all signals carry the same weight across industries. For fintech companies, a regulatory approval signal might be worth +35 points (it unlocks new markets and revenue). For an e-commerce company, a holiday season hiring surge is routine and might only warrant +5 points instead of the standard +20.
Build an industry modifier layer that adjusts base scores:
INDUSTRY_MODIFIERS = {
"fintech": {"funding_round": 1.3, "regulatory_approval": 1.5, "hiring_surge": 0.9},
"ecommerce": {"hiring_surge": 0.5, "expansion": 1.4, "new_product_launch": 1.3},
"healthtech": {"funding_round": 1.2, "key_hire": 1.4, "partnership": 1.3},
}
These modifiers ensure your scoring model reflects the nuances of each vertical, reducing false positives and improving lead quality across your pipeline.
Integration with Popular CRMs
Your signal-enriched lead scores need to live where your sales team works. Here's how to integrate with the three most popular CRMs:
HubSpot
Use HubSpot's custom properties and workflows. Create a custom contact property called signal_score (number type) and update it via the HubSpot API. Set up workflow triggers based on score thresholds: when signal_score crosses 80, auto-assign to a sales rep and create a task. HubSpot's native lead scoring can run alongside your signal score, giving reps both views.
Salesforce
Create a custom field on the Lead/Contact object for the signal score. Use Salesforce Flow or Apex triggers to route leads when the score changes. For enterprise teams, consider pushing signal data into a custom object (Company_Signal__c) linked to the Account, giving reps full signal history in the account view. Salesforce's platform supports webhook ingestion via Platform Events, which pairs perfectly with the BounceWatch webhook model.
Pipedrive
Pipedrive's custom fields and automations make this straightforward. Create a custom deal/person field for signal score, update via API, and set up automations to move deals between pipeline stages when scores change. For smaller teams, Pipedrive's simplicity is an advantage — you can have signal-based routing running in under an hour.
For all three CRMs, the pattern is the same: receive signal webhook → recalculate score → push updated score to CRM → trigger CRM automation. The BounceWatch API handles the signal detection; your integration layer handles the scoring math and CRM sync.
If you're evaluating enrichment tools for this pipeline, our Clearbit alternatives comparison and BounceWatch vs Apollo breakdown cover the key differences in signal coverage and API design.
Getting Started
Building a signal-based lead scoring system doesn't require ripping out your existing infrastructure. Start with these steps:
- Audit your current scoring model. What percentage of your score comes from behavioral data vs. firmographic context? If the answer is "100% behavioral," you have the most to gain.
- Identify your highest-value signals. Talk to your sales team. Ask them: "What company event, if you knew about it in real time, would change how you prioritize a lead?" That's your starting signal set.
- Start with 3-5 signal types. Don't try to score all 40+ signal types on day one. Begin with funding, hiring surge, and layoffs — these are the highest-signal-to-noise events.
- Integrate the BounceWatch API. Fetch signals for your existing leads, calculate scores, and compare against your current prioritization. The delta will speak for itself.
- Set up webhooks for real-time updates. Once your scoring model is validated, switch from polling to webhooks for instant score updates.
The companies that win deals aren't the ones with the biggest sales teams — they're the ones that reach the right buyer at the right moment. Real-time company signals give you that timing advantage.
As noted by MarTech Series, the shift toward signal-driven sales is accelerating, with more B2B teams adopting event-based scoring models over static firmographic criteria. The developer community is increasingly building custom scoring pipelines that leverage APIs like BounceWatch rather than relying on monolithic sales platforms.
Ready to add company signals to your lead scoring? Explore the Signal Tracker for Sales Teams to see real-time signals in action, or jump straight into the API documentation to start building your lead scoring API integration today.