✨ From vibe coding to vibe deployment. UBOS MCP turns ideas into infra with one message.

Learn more
Andrii Bidochko
  • Updated: March 22, 2026
  • 7 min read

Implement Custom Lead Scoring in Your OpenClaw Sales Agent

You can implement a custom lead‑scoring micro‑service for the OpenClaw Sales Agent by building a lightweight API, containerizing it with Docker, and wiring it into your CRM pipelines via UBOS‑managed endpoints.

1. Introduction

In modern sales automation, custom lead scoring is the engine that decides which prospects get priority, which outreach cadence to apply, and ultimately, which deals close faster. Off‑the‑shelf scoring models are often too generic for niche B2B workflows, leading to missed opportunities.

OpenClaw, the open‑source sales agent platform, provides a flexible OpenClaw hosting guide that lets you extend its core with your own services. By creating a dedicated lead‑scoring micro‑service, you gain full control over criteria, weighting, and integration points while keeping the main agent lightweight.

2. Architecture Overview

Micro‑service design principles

  • Single responsibility: The service only calculates a numeric score based on input data.
  • Statelessness: Each request is independent, enabling horizontal scaling.
  • API‑first: Expose a RESTful endpoint that OpenClaw can call synchronously or asynchronously.
  • Observability: Emit structured logs and metrics for monitoring.

Interaction with CRM pipelines

The lead‑scoring service sits between the lead ingestion stage and the pipeline routing stage of OpenClaw. A typical flow looks like this:

  1. OpenClaw receives a new lead from a web form or third‑party source.
  2. Lead data is sent to the /score endpoint of the micro‑service.
  3. The service returns a score (e.g., 0‑100).
  4. OpenClaw updates the lead record and triggers the appropriate pipeline based on score thresholds.

3. Building the Lead‑Scoring Service

Setting up the project

We’ll use Python 3.11 with FastAPI for rapid development. Create a new directory and initialise a virtual environment:

mkdir lead‑scorer
cd lead‑scorer
python -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn pydantic

Defining scoring criteria and data model

Start with a Pydantic model that mirrors the fields OpenClaw will send:

from pydantic import BaseModel
from typing import List, Optional

class Lead(BaseModel):
    email: str
    company_size: int          # number of employees
    annual_revenue: float
    industry: str
    last_website_visit: Optional[str] = None
    engagement_score: Optional[int] = 0
    tags: List[str] = []

Implementing the scoring algorithm

The algorithm below demonstrates a flexible rule‑engine approach. Each rule returns a partial score; the final score is the sum, capped at 100.

def rule_company_size(lead: Lead) -> int:
    if lead.company_size > 500:
        return 30
    elif lead.company_size > 100:
        return 20
    return 10

def rule_revenue(lead: Lead) -> int:
    if lead.annual_revenue > 5_000_000:
        return 25
    elif lead.annual_revenue > 1_000_000:
        return 15
    return 5

def rule_industry(lead: Lead) -> int:
    high_value = {"SaaS", "FinTech", "HealthTech"}
    return 20 if lead.industry in high_value else 5

def rule_engagement(lead: Lead) -> int:
    return min(lead.engagement_score * 2, 20)

def calculate_score(lead: Lead) -> int:
    score = sum([
        rule_company_size(lead),
        rule_revenue(lead),
        rule_industry(lead),
        rule_engagement(lead)
    ])
    return min(score, 100)

FastAPI endpoint

from fastapi import FastAPI, HTTPException

app = FastAPI(title="OpenClaw Lead Scorer")

@app.post("/score")
async def score_lead(lead: Lead):
    try:
        return {"score": calculate_score(lead)}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

Run the service locally with uvicorn main:app --reload. The endpoint is now ready for integration.

4. Testing the Service

Unit tests for scoring logic

import pytest
from main import Lead, calculate_score

def test_high_value_lead():
    lead = Lead(
        email="ceo@bigco.com",
        company_size=800,
        annual_revenue=10_000_000,
        industry="SaaS",
        engagement_score=8
    )
    assert calculate_score(lead) == 100

def test_low_value_lead():
    lead = Lead(
        email="john.doe@example.com",
        company_size=20,
        annual_revenue=50_000,
        industry="Retail",
        engagement_score=1
    )
    assert calculate_score(lead) == 30

Integration tests with mock CRM data

Use httpx to simulate OpenClaw calls:

import httpx
import asyncio

async def test_api():
    async with httpx.AsyncClient(base_url="http://localhost:8000") as client:
        payload = {
            "email": "alice@startup.io",
            "company_size": 150,
            "annual_revenue": 2_000_000,
            "industry": "FinTech",
            "engagement_score": 5,
            "tags": []
        }
        response = await client.post("/score", json=payload)
        assert response.status_code == 200
        assert response.json()["score"] == 80

asyncio.run(test_api())

Load testing considerations

For production readiness, run a Locust or k6 script that spikes 200 RPS and monitors latency. Keep the 95th‑percentile response time under 200 ms.

5. Deploying the Service

Containerization with Docker

# Dockerfile
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Build and push the image to your registry:

docker build -t your-registry/lead‑scorer:latest .
docker push your-registry/lead‑scorer:latest

CI/CD pipeline steps

UBOS’s Workflow automation studio can orchestrate the following pipeline:

  1. Run unit & integration tests on each commit.
  2. Build Docker image and push to registry.
  3. Trigger a rolling update on the Kubernetes cluster managed by UBOS.
  4. Post‑deployment health check (call /score with a dummy payload).

Monitoring and logging

Integrate with Enterprise AI platform by UBOS to collect:

  • Structured JSON logs (timestamp, request_id, latency, score).
  • Prometheus metrics: http_requests_total, request_duration_seconds.
  • Alert on error rate > 1% or latency > 300 ms.

6. Integrating with OpenClaw CRM Pipelines

API endpoints for score retrieval

OpenClaw expects a simple POST endpoint that returns {"score": int}. Register the endpoint URL in the OpenClaw configuration file (openclaw.yaml) under lead_scoring_service:

lead_scoring_service:
  url: https://lead‑scorer.yourdomain.com/score
  timeout_seconds: 5

Updating lead status based on score

Define score thresholds in the pipeline DSL:

pipeline:
  - name: "High‑Value"
    condition: "score >= 80"
    action: "assign_to: senior_sales_rep"
  - name: "Medium‑Value"
    condition: "score >= 50"
    action: "assign_to: junior_sales_rep"
  - name: "Low‑Value"
    condition: "score < 50"
    action: "nurture_campaign"

Example workflow configuration

Below is a minimal workflow.yaml that ties everything together. Notice the use of the Web app editor on UBOS to edit this file directly in the browser.

steps:
  - id: ingest_lead
    type: webhook
    endpoint: /api/leads
  - id: score_lead
    type: http
    method: POST
    url: "{{ config.lead_scoring_service.url }}"
    body: "{{ steps.ingest_lead.payload }}"
    output: score_response
  - id: route_lead
    type: decision
    expression: "score_response.score"
    branches:
      - when: ">=80"
        then: assign_senior
      - when: ">=50"
        then: assign_junior
      - when: "<50"
        then: start_nurture

7. Best Practices & Tips

Keeping scoring rules flexible

  • Store rule weights in a JSON config that can be hot‑reloaded without redeploying.
  • Expose an admin UI (e.g., via AI marketing agents) for non‑technical marketers to tweak thresholds.

Security and data privacy

  • Enforce TLS for all inbound/outbound traffic.
  • Sanitize incoming payloads; use Pydantic’s strict typing.
  • Mask personally identifiable information (PII) before logging.

Performance optimization

  • Cache static lookup tables (e.g., industry weight map) using functools.lru_cache.
  • Run the service on a CPU‑optimized node; scoring is CPU‑bound, not GPU‑bound.
  • Profile with cProfile and eliminate hot loops.

8. Conclusion

By following the steps above, you have built a custom lead‑scoring micro‑service, validated it with unit and integration tests, containerized it for reliable deployment, and wired it into OpenClaw’s CRM pipelines. This architecture gives you full control over scoring logic, ensures scalability, and keeps the core sales agent lean.

Ready to host your service on UBOS? Check out the detailed OpenClaw hosting guide for one‑click deployment, automatic SSL, and built‑in monitoring.

Need a quick start? Explore UBOS for startups or browse the UBOS templates for quick start to accelerate future micro‑services.

Happy scoring, and may your pipelines be ever efficient!

Further Reading & Resources


Andrii Bidochko

CTO UBOS

Andrii Bidochko is an AI entrepreneur and researcher focused on AI agents, reinforcement learning, and autonomous systems. He writes about the technologies shaping the future of machine intelligence, from frontier models and agent architectures to real-world AI applications.

Sign up for our newsletter

Stay up to date with the roadmap progress, announcements and exclusive discounts feel free to sign up with your email.

Sign In

Register

Reset Password

Please enter your username or email address, you will receive a link to create a new password via email.