> For the complete documentation index, see [llms.txt](https://support.parvenu.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://support.parvenu.io/features/flows/enrichment-and-ai-steps.md).

# Enrichment and AI Steps

Steps that add data to each lead. These run once per lead.

These steps run against every lead in turn. Most of them only charge when they find something.

{% hint style="info" %}
The credit cost of each step is shown in the Flow builder, and an estimate for the whole run is shown before you start it.
{% endhint %}

## Enrichment

| Step                       | What it does                                                                                                                                                    | Needs                                   |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| LinkedIn Profile Lookup    | Title, company, location and more from the person's LinkedIn profile.                                                                                           | LinkedIn URL                            |
| Person + Company           | Profile plus company details in one step. A company already checked on the lead's list recently is not charged again.                                           | LinkedIn URL                            |
| Company Profile            | Full company record from its LinkedIn page. Leads at the same company share one lookup, and a company checked on the lead's list recently is not charged again. | Company LinkedIn URL                    |
| Company From Domain        | Turns a website domain into a full company record.                                                                                                              | Company website                         |
| Find Company Website       | Finds the company website from its name. Leads at the same company in one run share a single lookup and a single charge.                                        | Company name                            |
| Find Hiring Manager        | Finds who to email about the job a company is hiring for, with a valid email. The lead becomes that person.                                                     | Company website or Company LinkedIn URL |
| Company Headcount          | Exact employee count and company size range from the website domain. When only a range is known, only the size is filled.                                       | Company website                         |
| Technology Stack           | Reads which tools the company's website runs - analytics, CMS, ecommerce, ad pixels, CRM, hosting.                                                              | Domain (company website)                |
| Job Function Breakdown     | Staff counts per job area - Sales, Ops, Engineering and so on.                                                                                                  | Company LinkedIn URL or website         |
| Find LinkedIn URL          | Finds a LinkedIn profile from name and company.                                                                                                                 | Name + company                          |
| Recent LinkedIn Posts      | Pulls the person's recent posts. Filter by how recently they posted.                                                                                            | LinkedIn URL                            |
| Work Email Lookup          | The person's own verified work email.                                                                                                                           | LinkedIn URL, or Name + company domain  |
| Personal Email             | Personal email address.                                                                                                                                         | LinkedIn URL                            |
| Mobile Phone               | Mobile number. Has an **Also validate the phone** setting, off by default.                                                                                      | LinkedIn URL                            |
| Validate Phone             | Checks the lead's mobile phone with your own Phone Validator key: phone type, phone company, fake number and phone location.                                    | Mobile phone                            |
| Open-to-Work Check         | Whether the person is currently open to work on LinkedIn.                                                                                                       | LinkedIn URL                            |
| Work History and Education | Past jobs and education.                                                                                                                                        | LinkedIn URL                            |

**LinkedIn Profile Lookup** and **Person + Company** both have a **Full profile** setting. Leave it off for the basics, turn it on when you want the whole profile.

**Find Company Website** looks each company name up once per run. The first lead at a company gets the lookup; the others at that company reuse the answer for free, and may show **waiting for company website** for a few seconds while the first lookup finishes. Different spellings of a name ("ServiceTitan", "Service Titan") count as different companies.

**Company Profile** looks each company up once per run, the same way: the first lead at a company gets the lookup, the others at that company reuse the answer for free, and may show **waiting for company profile** for a few seconds while it finishes. Spellings of the same company LinkedIn URL count as one company.

**Company Profile** and **Person + Company** also remember companies on the lead's list. A company already checked and charged on that list recently, by an earlier run, the leads table, the API or the connector, is not looked up or charged again: Company Profile is free for it, and Person + Company charges only for the person. A company that was not checked recently is looked up, and charged, as usual. Leads that are not on a list (sent by a webhook or passed straight into a run) are looked up every time.

**Find Hiring Manager** is made for leads that come from a job search. It tries the person who posted the job first (kept even when they work in HR), then the title in its **Title the job reports to** setting, then the company's CEO, President, CFO, COO, Founder or Executive Director. The setting can be a placeholder such as `{{ai.generated_text}}` from a **Personalize with AI** step that read `{{job.description}}`. Each company is searched once per run, a company where nobody with a valid email is found is skipped at no cost, and the person found becomes the lead, so the steps after it (Mobile Phone, an export) work on them. The details are also under `hiring_manager.*`, with `hiring_manager.hiring_manager_source` saying how they were found.

**Work Email Lookup** also fills in `base.email` when the lead doesn't have one yet, so an email export can come straight after it. An email that belongs to a past employer is not used - the lead's history shows "Old Email Found" and the lookup keeps looking for a current one. A lead that already has a verified current work email is skipped.

**Work Email Lookup** does not need a LinkedIn URL: first name, last name and the company website are enough. Titles and letters after the name are dropped first. A free address (Gmail, Yahoo and similar) or someone else's address already on the lead does not count as a work email, so the lookup still runs. The step never puts a free address, someone else's address or a shared inbox (frontdesk@, info@) into `base.email`. When no address is found, it tries the usual address patterns at the company website (first.last@, first@ and so on) and keeps the first one that checks out. If the website accepts every address, it does not guess.

**Validate Phone** needs your Phone Validator key saved on the Integrations page; without it the step fails and says so. It writes `phone_type`, `phone_company`, `fake_number` and `phone_location` to the lead and to `phone_check.*`. A fake number is kept on the lead with **Fake Number** set to Yes, so follow the step with an **If / else** on `base.fake_number` is `No` to keep only real numbers. A lead with no mobile phone is skipped. You can also switch on **Also validate the phone** in the **Mobile Phone** step to check each number as soon as it is found. More on the [Phone Validator](/features/integrations/phone-validator.md) page.

{% hint style="warning" %}
**Job Function Breakdown** only counts staff who have a LinkedIn profile, so the numbers are a floor, not a headcount.
{% endhint %}

## AI steps

| Step                   | What it does                                                           | Writes to                               |
| ---------------------- | ---------------------------------------------------------------------- | --------------------------------------- |
| ICP Scoring            | Scores each lead against an ideal customer profile you have saved.     | `icp.score`, `icp.is_match`             |
| Multi-ICP Score        | Checks each lead against 2 to 10 of your ICPs and keeps the best fit.  | `icp.name`, `icp.score`, `icp.is_match` |
| Personalize with AI    | Writes personalised text for each lead - an email opener, for example. | `ai.generated_text`                     |
| Research with AI       | Free-form research about the lead or their company.                    | `ai.research`                           |
| Scrape Website with AI | Reads the company website and answers your question. Slow.             | `ai.website_scrape`                     |
| Find Company News      | Finds the company's recent news from its website.                      | `ai.company_news`                       |

### Who to score

**ICP Scoring** and **Multi-ICP Score** both have a **Who to score** setting:

* **People not scored yet** (the default) - A lead that already has a score for the same ICP(s), saved since they were last changed, keeps it and is not charged again. It may come from an earlier run, the leads table, the API or the connector.
* **Everybody** - Score every lead in the run again and use only the new scores.

Either way, a run only scores its own leads, never the rest of the list. A list-watch Flow that starts a new run each time leads arrive pays only for the new ones.

### ICP Scoring

`icp.score` runs from 0 (poor fit) to 1 (perfect fit). `icp.is_match` is **true** when the score clears the threshold set on your ICP. Branching on `icp.is_match` is usually easier than picking a number yourself.

The run's leads are scored in the background, about 200 leads a minute. A lead that reaches this step before its score is ready waits for it and then carries on - the run shows it as **waiting for score**, not as a failure. A lead only fails at this step if scoring has not finished after 3 hours.

The step only uses a score for the ICP you picked, saved since that ICP was last changed. A score for a different ICP is ignored.

### Multi-ICP Score

Pick 2 to 10 of your saved ICPs. `icp.name` is the ICP the lead fits best, or **No match** if it fits none. `icp.score` is that ICP's score on the same 0 to 1 scale as ICP Scoring, and `icp.explanation` lists every ICP's score.

It waits for scores the same way ICP Scoring does. It only uses a score for exactly the ICPs you picked, so a result for other ICPs on the lead is never mistaken for this one. Follow it with an **If / else** on `icp.name` to send each market down its own path. More on the [Multi-ICP Score](/features/enrich/multi-icp-score.md) page.

### Writing prompts

**Personalize with AI**, **Research with AI** and **Scrape Website with AI** all take a prompt. Use `{{field}}` placeholders to drop lead data into it:

```
Write a one-sentence opener for an email to {{base.first_name}},
who is {{base.current_title}} at {{base.organization_name}}.
Mention something specific from {{profile.about}}. No greeting, no sign-off.
```

The result is written back to the lead so later steps - and your export - can use it. The full list of common fields is on the Flows page.

### What the AI steps save to your list

For leads that come from a Parvenu list, each AI step saves its answer onto that lead's row and adds a line to the lead's history in the leads table, marked **Flow**. The line says whether text was found and what it cost; an attempt that fails or finds no news costs nothing and says so.

A lead from a list needs a **LinkedIn URL**, an **email**, or a **name and company** for the answer to be saved. A lead with none of these is skipped by the AI steps and **not charged**. Leads sent to a flow by a webhook, or passed straight into a run, are not on a list, so they always go through and their answer is available to the next steps.

**Find Company News** and **Scrape Website with AI** need a company website. A lead with no website, or with a website that doesn't exist, is skipped by that step at no cost - its history says "Skipped (no domain)" or "Website not found" - and the lead carries on to the next step in the flow.

{% hint style="success" %}
Put **ICP Scoring** or **Multi-ICP Score** early and follow it with an **If / else** step. Only the leads that match go on to the expensive email and phone lookups.
{% endhint %}
