> For the complete documentation index, see [llms.txt](https://developer.parvenu.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.parvenu.io/enrichments/scrape-website-with-ai/list-lookup.md).

# List Lookup

Read every row's company website and answer a prompt from its contents. Asynchronous, writes results back into the list.

<mark style="color:green;">`POST`</mark> `/scrape_website_with_ai_list`

{% hint style="danger" %}
Your `prompt` **must reference at least one column** using `{{column_name}}` syntax. A prompt with no column reference is rejected with a 400, see Prompt requirements below.
{% endhint %}

{% hint style="warning" %}
Rows need a company website before this will work. If the website column is empty, run [Website Lookup](/enrichments/website-enrichment.md) first.
{% endhint %}

This is an **asynchronous** endpoint. Poll `/check_list_status` until the list reports `done`, then fetch the rows with `/download_list`. Costs **1 credit per company**, charged only when the model returns text. Results are written to the `scrapewebsite_with_ai` column.

**Charged once per company.** Contacts at the same company (the same website domain) share one answer. The website is read and charged once, and the other contacts at that company get the same answer for 0 credits, with `(same company)` in their `log`. Rows with no website domain are not grouped and are handled one by one, as before.

Use this to run a prompt against every row's website in one call, rather than looping over [Individual Lookup](/enrichments/scrape-website-with-ai/individual-lookup.md) per row.

**Headers**

| Name         | Value              |
| ------------ | ------------------ |
| Content-Type | `application/json` |

**Body**

| Name         | Type   | Description                                                                                                                                                                 |
| ------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api_key`    | string | Your API Key.                                                                                                                                                               |
| `listname`   | string | Name of the existing Parvenu list to enrich.                                                                                                                                |
| `prompt`     | string | The prompt to run against each row. Must contain at least one `{{column_name}}` reference.                                                                                  |
| `view`       | string | Optional. Which rows of the list to process. `all` (default) processes every contact in the list; `verified` restricts the run to contacts whose email address is verified. |
| `saved_view` | string | Optional. Name of a saved view on this list. Runs only on the contacts in that view. Don't combine with `view`, `filter_stack` or `search`.                                 |

**Saved views.** To run only on the contacts in a saved view, send its name as `saved_view`. See [List Saved Views](/manage-lists/list-saved-views.md).

**Prompt requirements**

Reference list columns with double curly braces. The API substitutes each row's value before reading the website:

```
What services does {{organization_name}} offer at {{company_website}}?
```

A prompt with no column reference fails with a 400 and the message `No column references found in prompt. Use {{column_name}} format.`

**View values**

| Value      | Processes                                  |
| ---------- | ------------------------------------------ |
| `all`      | Every row in the list (default).           |
| `verified` | Only rows whose email address is verified. |

**Example**

{% tabs %}
{% tab title="Input" %}

```json
{
  "api_key": "your_api_key",
  "listname": "my_list",
  "prompt": "What does {{organization_name}} sell? Answer in one sentence."
}
```

{% endtab %}

{% tab title="Output" %}

```json
{
  "success": true,
  "job_id": "210",
  "status": "queued",
  "list_name": "my_list",
  "rows_selected": 10,
  "rows_fetched": 10,
  "message": "Web GPT prompt saved/updated with ID 210. Loaded 10 row(s). Scrape processing started in background.",
  "view": "all",
  "max_rows": 5000,
  "truncated": false,
  "credits_used": 0
}
```

{% endtab %}

{% tab title="Error" %}

```json
{
  "status": "error",
  "error": {
    "code": "http_error",
    "message": "Failed to start AI website scrape due to external API error",
    "detail": "External API error: 400 - No column references found in prompt. Use {{column_name}} format."
  },
  "success": false
}
```

{% endtab %}
{% endtabs %}

**Reading the acknowledgement**

Every list-scoped trigger answers with the same envelope, so one piece of client code handles them all.

| Field           | Meaning                                                                                     |
| --------------- | ------------------------------------------------------------------------------------------- |
| `job_id`        | Identifier for this run. Always a string. For AI triggers it is the id of the saved prompt. |
| `status`        | A job status: `queued`, `processing`, `done`, `not_found`, `cancelled` or `error`.          |
| `rows_selected` | How many rows matched your `view` before the page limit was applied.                        |
| `rows_fetched`  | How many rows this run actually picked up. This is the number that gets processed.          |
| `max_rows`      | The ceiling a single run will fetch.                                                        |
| `truncated`     | `true` when the list was longer than `max_rows` and the run was cut to fit.                 |

{% hint style="info" %}
This endpoint reads a live page per company and is slow: roughly 25 seconds a site. Try a new prompt on a short list first; the prompt is saved and reused on later runs, so a bad prompt overwrites good results.
{% endhint %}

**Retrieving results**

* [Check List Status](/get-enrichment-results/check-list-status.md)
* [Download List Data](/get-enrichment-results/download-list-data.md)
