How to Use Company Signals in Your API for Smarter Lead Scoring

Api Data ·
Bounce Watch Bounce Watch Team
· · 17 min read · 164 views
How to Use Company Signals in Your API for Smarter Lead Scoring

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:

  1. Behavioral signals — what the individual is doing (page visits, form fills, email engagement)
  2. 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:

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:

  1. 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.
  2. 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.
  3. 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.
  4. Integrate the BounceWatch API. Fetch signals for your existing leads, calculate scores, and compare against your current prioritization. The delta will speak for itself.
  5. 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.

Lead Scoring Company Signals API Signal Intelligence Developer Tutorial Sales Automation API Integration
Share
Bounce Watch

Bounce Watch Team

Published on March 09, 2026

All Articles

Access startup data via our powerful API

Enrich your CRM, build integrations, and automate company research with the Bounce Watch API.

One analytics cookie (Google Analytics). Cookie Policy