Skip to content
Score Company Websites Against Your ICP with Jev
Article

Score Company Websites Against Your ICP with Jev

Guide

Create a company scoring workflow using public website evidence, an explicit ICP rubric, Jev decisions, and human review for incomplete records.

By MrScraper Team 12 min read

Jev lead scoring rates how well a company fits your ideal customer profile (ICP), using facts from its public website. MrScraper collects the company's description, products, and quoted evidence. Jev scores each ICP dimension separately. Your code combines the scores with your own weights and sends unclear companies to a person.

TL;DR

  • Score fit, not intent. A website shows what a company does. It does not show whether it is ready to buy.
  • One question per dimension. Score industry, offering, and market separately, then weight them in code.
  • Unknown is not zero. Missing evidence sends a company to review instead of the bottom of the list. Most account lists are long, and most of the useful facts sit on company websites. Reading every "About" page by hand does not scale. This guide shows how to turn public website evidence into a ranked, reviewable account list. It is a custom workflow, and every number it produces should be checked against your own labeled examples.

New to Jev? Read What Is Jev? first. For the Python basics used below, see Classify Web Data with Jev and MrScraper.

How can Jev support company website lead scoring?

Jev can rate each company against a rubric you write, using only the evidence you extracted from its website. It returns a position on each scale plus a confidence value. That gives your team a consistent first pass, with every score tied to a quote and a source URL.

Score company fit using visible evidence

TypeSafe lists matching company profiles to an ideal customer profile as an example use case in its use case map. This guide turns that idea into a concrete, testable workflow.

The key word is visible. A good website fit signal is something a reviewer can point to on the page:

  • "We sell handmade furniture online and ship across Europe." This is a visible fact.
  • "They are probably growing fast." This is an inference, and it does not belong in a fit score. Keeping to visible facts has two benefits. Reviewers can check every score in seconds. And the model is less likely to be pulled around by marketing language. TypeSafe's Jev 1.13 notes warn that text written to argue for its own classification can move the answer. Short, factual quotes are harder to oversell than a whole homepage.

How do you define an ICP rubric?

Write down each part of your ICP as its own dimension, with plain-language levels that describe real situations. Keep industry, offering and market separate. Add hard disqualifiers, like being a competitor, as yes/no checks that your code applies as a gate.

Separate industry, offering and market criteria

Here is an example rubric. It is author-created for a fictional company that sells returns-management software to online stores. Swap in your own ICP.

Dimension Jev question type Levels or condition Weight
Industry Score (4 levels) 0: Not retail or e-commerce · 1: Retail, mostly in physical stores · 2: Sells online, mixed with other channels · 3: Online-first retailer 0.40
Offering Score (3 levels) 0: Sells services or digital goods only · 1: Sells some physical products · 2: Physical products are the core business 0.35
Market Score (3 levels) 0: Sells only to businesses · 1: Sells to both businesses and consumers · 2: Sells mainly to consumers 0.25
Competitor Noul (gate) "The company sells returns-management or reverse-logistics software." Exclude if yes

Some rules for writing a rubric that works:

  • Describe situations, not degrees. "Online-first retailer" gives Jev something to match. "High fit" does not. TypeSafe's Score docs make the same point.
  • One idea per dimension. A level like "online, consumer-focused and international" mixes three things. Split it.
  • Keep numbers in code. Jev 1.13 is weak at math and counting, according to TypeSafe. If size matters, extract a stated figure and compare it in code, or leave size out.
  • Use 2 to 10 levels. That is the range the Score type accepts. Three or four clear levels usually beat ten fuzzy ones.

Which website facts should MrScraper collect?

Collect a short company description, the main products or services, who the company sells to, and verbatim quotes that support each point. Store the page URL with every quote. Collect public company facts only, not personal contact data.

Company descriptions, products and cited source passages

For each company, the homepage and "About" page usually hold most of the evidence. A shipping or FAQ page often shows whether a company sells online and to whom. MrScraper's Map agent can list a site's URLs so you can pick those pages, and the General agent can extract fields from each one.

Field Typical page Example value Feeds
company_name Homepage "Oak & Ash Studio" Record ID
description About page One or two sentences about the business Industry, Offering
products_or_services Homepage, shop List of main product lines Offering
customer_types About, FAQ "home owners", "interior designers" Market
sales_channels Homepage, FAQ "online shop", "showroom" Industry
evidence_quotes Any page Exact sentences copied from the page Review and audit
source_url Your code The page each value came from Review and audit

An extraction prompt for the General agent can ask for these directly:

text
Extract as JSON:
- company_name (string)
- description (one or two sentences, copied from the page where possible)
- products_or_services (list of strings)
- customer_types (list of strings, only if stated on the page)
- sales_channels (list of strings, only if stated on the page)
- evidence_quotes (list of exact sentences copied from the page that support the fields above)
Use null for anything not stated on the page. Do not guess.

The last line matters most. "Use null" keeps unknowns visible, so your code can tell the difference between "this company sells to businesses" and "the page does not say."

How do you turn evidence into Jev questions?

Ask one Score question per ICP dimension and one Noul per disqualifier, all in a single request. Next to each Score, ask a Noul that checks whether the evidence covers that dimension at all. Then normalize the scores and combine them with your weights in code.

Score each dimension; combine weights in code

This follows TypeSafe's composite scoring pattern: break a judgment into separate scores, normalize each to 0 to 1, and weight them in code.

python
from typesafe_sdk import Noul, Score, TypeSafeClient
 
DIMENSIONS = {
    "industry": (0.40, Score(
        instructions="Which best describes the business in `evidence`?",
        criteria=[
            "Not a retail or e-commerce business",
            "A retailer that sells mostly in physical stores",
            "Sells online, alongside other sales channels",
            "An online-first retailer",
        ],
    )),
    "offering": (0.35, Score(
        instructions="What does the company in `evidence` mainly sell?",
        criteria=[
            "Services or digital goods only",
            "Some physical products alongside services",
            "Physical products are the core business",
        ],
    )),
    "market": (0.25, Score(
        instructions="Who does the company in `evidence` sell to?",
        criteria=[
            "Only to other businesses",
            "To both businesses and consumers",
            "Mainly to consumers",
        ],
    )),
}
 
COVERAGE = {
    "industry": "Does `evidence` say how or where the company sells?",
    "offering": "Does `evidence` say what the company sells?",
    "market": "Does `evidence` say who the company's customers are?",
}
 
COMPETITOR = Noul(
    instructions="Does the company in `evidence` sell returns-management or reverse-logistics software?"
)
 
 
def build_questions() -> dict:
    questions = {name: q for name, (_, q) in DIMENSIONS.items()}
    questions.update({f"{name}_covered": Noul(instructions=text) for name, text in COVERAGE.items()})
    questions["is_competitor"] = COMPETITOR
    return questions
 
 
def score_company(client: TypeSafeClient, company: dict) -> dict:
    state = {
        "evidence": {
            "description": company["description"],
            "products_or_services": company["products_or_services"],
            "customer_types": company["customer_types"],
            "sales_channels": company["sales_channels"],
            "quotes": company["evidence_quotes"],
        }
    }
    answers = client.system_one(state=state, questions=build_questions()).answers
 
    dims = {}
    for name, (weight, question) in DIMENSIONS.items():
        top = len(question.criteria) - 1
        dims[name] = {
            "score": answers[name].score / top,          # normalized 0 to 1
            "confidence": answers[name].confidence,
            "covered": answers[f"{name}_covered"].noul,
            "weight": weight,
        }
 
    fit = sum(d["weight"] * d["score"] for d in dims.values())
    return {"fit": round(fit, 3), "dims": dims, "competitor": answers["is_competitor"].noul}

Why this shape works:

  • Every question sees the same evidence. TypeSafe evaluates the questions in parallel and in isolation, so one answer never leaks into another.
  • Coverage questions catch gaps. A low market score could mean "sells to businesses" or "the page never says." The _covered Noul tells them apart.
  • Weights live in code. When the ranking disagrees with your team, change a number and rerun. You do not need to rewrite a prompt.

How do you handle unknown or ambiguous companies?

Route them to a person instead of forcing a score. A company with missing evidence on a heavy dimension, a split competitor check or low confidence should land in a review queue. Only clear, well-covered companies get an automatic tier.

Missing evidence and human review

Turn the answers into a decision with explicit rules:

python
YES, NO = 0.8, 0.2
MIN_CONFIDENCE = 0.5  # starting point; tune on labeled examples
 
 
def decide(result: dict) -> str:
    if result["competitor"] >= YES:
        return "exclude: competitor"
    if NO < result["competitor"] < YES:
        return "review: possible competitor"
 
    for name, d in result["dims"].items():
        if d["covered"] < NO and d["weight"] >= 0.3:
            return f"review: no evidence for {name}"
        if d["covered"] >= NO and d["confidence"] < MIN_CONFIDENCE:
            return f"review: unclear {name}"
 
    if result["fit"] >= 0.75:
        return "tier A"
    if result["fit"] >= 0.5:
        return "tier B"
    return "tier C"
Situation Rule Outcome
Clearly a competitor is_competitor at or above 0.8 Exclude
Maybe a competitor is_competitor between 0.2 and 0.8 Review
Heavy dimension not covered _covered below 0.2, weight 0.3 or more Review
Dimension covered but split Confidence below 0.5 Review
Everything clear Use the fit score Tier A, B or C

These thresholds are starting points, not recommendations. TypeSafe's Confidence docs say the right values depend on your domain and should be tuned on your own data.

Make review fast. Show the reviewer the company name, each dimension score, the evidence quotes, and the source URLs on one screen. Store their decision as a label. Those labels become your next test set.

How do you evaluate account-scoring quality?

Compare Jev's ranking with fit decisions your team has already made. Label a small set of companies by hand, score them with the workflow, and check whether the top of the list matches your best-fit accounts. Fix the rubric where they disagree.

Compare rankings with labeled fit decisions

A practical first test, offered as a proposal rather than a benchmark:

  1. Pick 20 to 30 companies. Include clear fits, clear non-fits, a competitor or two, and a few hard cases. This small set is a starting check, not proof of accuracy.
  2. Label them blind. Have someone on your team mark each as a good fit, maybe, or poor fit, without seeing the scores.
  3. Run the workflow with a pinned model version, such as jev-1.13.0.
  4. Compare. How many of the top 10 by fit score did your team label "good fit"? How many "poor fit" companies landed in tier A? How many went to review?
  5. Read every disagreement. Look at the quotes. Often the rubric level was vague, or the extraction missed a key page. Record the results in an evidence-linked table so anyone can audit a score:
Company Industry Offering Market Fit Key evidence (quote) Source URL Team label Agree?
Example Co A 0.67 1.00 1.00 0.87 "We design and sell furniture online..." example-a.com/about Good fit Yes
Example Co B 1.00 0.00 0.50 0.53 "Our agency builds Shopify stores..." example-b.com Poor fit No

In the second example row, a web agency scored high on industry because it works with online stores. That is the kind of miss this table helps you catch. The fix is to sharpen the industry levels so they describe a company that sells online, not one that serves online sellers.

Rerun the test whenever you change the rubric, the extraction prompt, or the model version.

Frequently asked questions

Can a website prove buying intent?

No. A website shows visible fit signals, such as what a company sells and who it sells to. Buying intent means a company is actively looking for a solution now, and a public website rarely shows that. Treat website scores as fit evidence and look for intent signals in other sources.

What is the difference between ICP fit and lead readiness?

ICP fit asks whether a company matches the kind of customer you serve best. Lead readiness asks whether that company is ready to talk or buy right now. Website evidence supports fit scoring. Readiness usually depends on engagement, timing, and conversations, which your sales process tracks separately.

How do I score companies with incomplete data?

Keep missing facts as unknown instead of scoring them as zero. Ask a coverage question for each dimension, and route companies with no evidence on an important dimension to review. A reviewer can check another page or mark the company as unscored. This keeps gaps from pushing good accounts down.

Does MrScraper provide contact data?

This workflow uses only public company facts, such as descriptions, products, customer types, and sales channels, with their source URLs. It does not collect personal contact details. Extract only the fields you need from pages you are allowed to access, and follow the privacy rules that apply to your data.

Can Jev replace a sales qualification team?

No. Jev is decision support. It gives your team a consistent first pass over many companies, with scores tied to evidence. People still review unclear cases, set the rubric and weights, and make the final call. Use labeled examples to check that the scores match your team's judgment.

Facts about Jev checked against TypeSafe's official documentation on October 13, 2026. Jev is in early access, and its API and limits may change. The rubric, weights, and thresholds in this guide are examples, not tested recommendations.

Summarize this post

Open it in your assistant of choice with the prompt ready to send.

Take a Taste of Easy Scraping!

Your choices

Cookie preferences

Necessary cookies keep your selection. Optional categories are disabled until you switch them on.

Strictly necessary

Remembers your privacy selection and keeps the site working.

Always on