# Lead scoring

> Grade every contact A to D against your ideal customer profile, see the reason behind each grade, and optionally fill in missing company facts through Looot inside a budget.

Source: https://docs.ayinbox.com/guides/lead-scoring/

Lead scoring compares each contact with the customers you want to reach and gives it a grade from **A** (best fit) to **D**, with a score out of 100 and the reason behind every part of it. Grades show in the contact list, in the contact drawer, and as a filter and a segment condition, so you can send your best-fitting contacts first.

Scoring reads what is already on your contacts: their title, company, country, and the custom fields [Looot lead jobs](/guides/looot-leads/), [Apollo](/guides/apollo/), [Clay](/guides/clay/) and [imports](/guides/contacts-crm/#importing) fill in. It costs nothing. Only the optional [company enrichment](#company-enrichment) spends money.

Set up your profile [#set-up-your-profile]

<Steps>
  <Step>
    Open **Settings > Lead scoring**. The page starts from an example profile for mid-market B2B software, sales and marketing buyers. Change it to match who you sell to.
  </Step>

  <Step>
    Give each criterion its points and what to match, and add any hard rules.
  </Step>

  <Step>
    Turn on **Score contacts**. Every contact is graded in the background, and the page shows how the grades split and how far the pass has got.
  </Step>
</Steps>

The page saves as you type. Seeing it takes **View contacts**; changing it takes **Manage contacts**, because a change re-grades every contact.

How a contact is scored [#how-a-contact-is-scored]

The profile has six criteria. Each earns points when the contact matches it:

| Criterion    | What it reads                                                         | How it earns                                                                                                  |
| ------------ | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Job title    | The contact's title                                                   | Full points when the title contains a word to target and none to avoid                                        |
| Seniority    | A level stated by an import or lead job, else one read from the title | The share of the points you give that level (C-suite, VP, head of, director, manager, senior, everyone else)  |
| Company size | An employee count on the contact, else the company's                  | Full points inside the ideal range, half inside the acceptable range, none outside it                         |
| Industry     | The contact's industry, else the company's                            | Full points for a target industry, none for one to avoid                                                      |
| Country      | The contact's country, else the company's                             | Full points for a target country. Names and two-letter codes both work, so United States and US are the same  |
| Tech stack   | A technologies field on the contact, else the company's               | Full points once enough of the technologies you look for are found; none when a technology you avoid is found |

The score is the share of the points earned, out of 100. A criterion with nothing to match (no words, no countries) is left out of the total. A fact nobody gave earns nothing and is marked unknown rather than guessed, so a contact with little data scores low until its data is filled in. The drawer says how many criteria had data.

Words match whole words and phrases, ignoring case: `sales` matches "Head of Sales" but not "Salesforce Admin".

The grade comes from the score and your thresholds. By default a score of 75 or more is an A, 55 a B and 35 a C; anything lower is a D.

Hard rules [#hard-rules]

A hard rule caps a contact at D whatever it scored, and the drawer shows which rule did:

* **Personal address with no company.** A Gmail, Outlook or similar address on a contact with no company domain.
* **Excluded domains.** Companies never to target, such as customers or partners. The company domain and the address's domain are both checked, and subdomains count.
* **Competitors.** A domain, or a name matched as words in the company name.
* **Disqualifying industries** and **disqualifying titles.**

Where grades show [#where-grades-show]

* **Contact list.** A **Grade** column with the letter and the score, sortable by score. It appears once any contact on the page is graded, and you can add or remove it with the column chooser.
* **Filter.** **Add filter > Lead grade** narrows the list to the grades you pick, or to contacts not scored yet. **Save as segment** keeps the filter.
* **Contact drawer.** The grade next to the name, and on the Overview tab the score, any hard rule, and what each criterion earned and why, with where each fact came from.
* **Segments.** **Lead grade** and **lead score** are [segment conditions](/guides/segments/), so a segment of A and B contacts stays current as grades change.
  **Lead grade is none of D** matches only graded contacts, so a contact not scored yet cannot slip past your hard rules into a campaign. To include contacts not scored yet, use **is any of A, B, C, not scored**.

When grades change [#when-grades-change]

* **New and edited contacts** are graded within a few minutes. Editing a contact's title, company or custom fields re-grades it.
* **Changing the profile** re-grades every contact in the background. Until a contact is done its old grade stays, and the drawer marks it as updating.
* **Turning scoring off** removes every grade, so every contact reads as not scored until you turn it back on, which grades everyone again at no cost. A segment that asks for grades stops matching while it is off and a linked campaign stops taking new leads from it, but one that lists **not scored** matches everyone, including contacts your hard rules would cap at D.

Grades update live for everyone in the workspace.

Company enrichment [#company-enrichment]

When your contacts lack company facts, a company enrichment run can look them up through [Looot](https://looot.ai/) on the instance's balance. It is off until the operator turns it on (`AYINBOX_LOOOT_SCORING`, see [configuration](/development/configuration/)), and the **Company enrichment** section only appears when it is.

**Enrich companies** starts a run. Pick a budget, from $0.05 to $50 ($5 by default), and whether to include the tech stack. The run:

* **Looks up only what scores.** A company is looked up only when one of its contacts lacks a fact your profile uses: size, industry or country from a company lookup, and the tech stack only when you included it and the profile scores technologies. Contacts with no company domain, and contacts a hard rule already caps at D, are skipped.
* **Looks each company up once.** Every contact at a company shares one lookup, and an answer, even one that found nothing, is reused for 90 days. A lookup that failed at the provider is not an answer, so the next run asks again. Facts on a contact always win over the company's.
* **Stays inside its budget.** Before each company the run reserves the most it could cost (up to $0.005 for the company and $0.015 for the tech stack). When the budget cannot cover that, the run stops and shows **Budget reached**. A lookup that finds nothing is usually free; you are charged only what Looot settles.
* **Is safe to interrupt.** A run saves its progress after every company. If the instance restarts or Looot does not answer in time, it picks up where it stopped, and repeated lookups are replayed rather than charged again.
* **Stops rather than guesses.** If Looot refuses a lookup outright, for example because the price is above the cap above, the run stops with the reason and records no answer for that lookup. A run Looot has left unanswered for 24 hours stops the same way, so it never blocks your next one.

One run can be in progress per workspace. Starting one takes **Use integrations** and **Manage contacts** and, on a hosted workspace, a paid plan that includes integrations.

Credits [#credits]

On an instance that bills with credits, each company is charged to the workspace once its lookups settle: the company's settled Looot spend divided by the operator's price per credit, rounded up. The default is one credit per $0.01, so a company lookup that cost $0.0019 is 1 credit, and one with its tech stack at $0.0119 is 2. A company is charged once per run, a cost Looot has not settled yet is held rather than billed, and before each company the run checks the workspace's balance, its spend limits and the member's limit could cover it at its most. When the workspace runs out of credits or reaches a [spend limit](/guides/ai-credits/#usage-and-spend-controls), the run stops with the reason, and keeps the company facts Looot already returned. Charges appear under **Settings > Billing** as **Looot company enrichment**, naming the company and the member who started the run.

Use the API [#use-the-api]

`GET /v1/lead-scoring/profile` returns the profile and `PUT /v1/lead-scoring/profile` replaces it:

```json
PUT /v1/lead-scoring/profile
{
  "enabled": true,
  "criteria": {
    "grades": { "A": 75, "B": 55, "C": 35 },
    "employees": { "points": 25, "ideal": { "min": 50, "max": 500 }, "acceptable": { "min": 20, "max": 2000 } },
    "industry": { "points": 20, "include": ["software", "saas"], "exclude": [] },
    "geography": { "points": 10, "include": ["US", "GB", "DE"] },
    "title": { "points": 15, "include": ["sales", "marketing", "founder"], "exclude": ["intern"] },
    "seniority": { "points": 20, "levels": { "c_suite": 1, "vp": 1, "head": 0.9, "director": 0.9, "manager": 0.6, "senior": 0.3, "entry": 0 } },
    "tech": { "points": 10, "include": ["HubSpot", "Salesforce"], "exclude": [], "min_matches": 1 },
    "disqualify": { "industries": ["government"], "titles": ["student"], "personal_email": true, "domains": ["acme.com"], "competitors": ["rival.io"] }
  }
}
```

Points run from 0 to 100 per criterion, seniority levels from 0 to 1, and each list holds up to 100 entries of up to 100 characters. A profile that cannot be scored is refused with `lead_scoring_invalid_profile` and a message naming the field. Saving the same profile again changes nothing.

`GET /v1/contacts/:id/lead-score` returns a contact's `grade`, `score`, `disqualified`, `reasons` (one per criterion, with `points`, `max`, `known`, `detail` and `source`), `coverage` and `scored_at`, or `null` before it is scored. `POST /v1/contacts/search` takes `lead_grades` and `sort_by: "lead_score"`, and each row carries `lead_score`. `GET /v1/lead-scoring/summary` counts the grades.

`POST /v1/lead-scoring/enrichment-runs` starts a company enrichment run with `max_cost_usd` and `include_technographics`; send an `Idempotency-Key` so a retry returns the same run. `GET /v1/lead-scoring/enrichment-runs` lists runs newest first (`limit` up to 100, `cursor`, and a `pagination` object with `next_cursor` and `has_more`), and it and `GET /v1/lead-scoring/enrichment-runs/:runId` report progress: `contacts_checked`, `domains_enriched`, `domains_missed`, `spent_micros` (settled spend in millionths of a dollar), `held_micros` (spend still being settled), `budget_reached` and `last_error`. See the [endpoint list](/api/endpoints/#lead-scoring) for scopes.

Good to know [#good-to-know]

* Lead scoring is a guide to who to contact first, built from the data you have. It is keyword matching, not a prediction, and it makes no claim about whether someone will reply.
* A [workspace export](/guides/workspace-export-import/) carries the profile, the grades and the company facts enrichment found; enrichment runs stay behind.
* Company facts from Looot are provider data. They are shown and scored as written and never followed as instructions.
