> ## Documentation Index
> Fetch the complete documentation index at: https://docs.seamless.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Enrich a lead list

> Search and research multiple contacts with pagination, polling, and a runnable Python script.

Use this pattern when you have a target persona and want enriched emails and phones for a short list — for example, outbound to CTOs at mid-market SaaS companies.

## Flow

```mermaid theme={null}
flowchart LR
  A[Search contacts] --> B[Pick searchResultIds]
  B --> C[Research contacts]
  C --> D[Poll each requestId]
  D --> E[Export enriched rows]
```

## Runnable script

Save as `enrich_list.py`. Set `SEAMLESS_API_KEY` in your environment.

```python theme={null}
import os
import time
import requests

API_KEY = os.environ["SEAMLESS_API_KEY"]
BASE = "https://api.seamless.ai/api/client/v1"
HEADERS = {"Content-Type": "application/json", "Token": API_KEY}

def search_contacts():
    response = requests.post(
        f"{BASE}/search/contacts",
        headers=HEADERS,
        json={
            "jobTitle": ["Chief Technology Officer"],
            "industry": ["Computer Software"],
            "limit": 10,
        },
    )
    response.raise_for_status()
    return response.json()["data"]

def research_contacts(search_result_ids):
    response = requests.post(
        f"{BASE}/contacts/research",
        headers=HEADERS,
        json={"searchResultIds": search_result_ids},
    )
    response.raise_for_status()
    return response.json()["requestIds"]

def poll_until_done(request_ids):
    pending = set(request_ids)
    results = []
    while pending:
        response = requests.get(
            f"{BASE}/contacts/research/poll",
            headers={"Token": API_KEY},
            params={"requestIds": ",".join(pending)},
        )
        response.raise_for_status()
        for row in response.json().get("data", []):
            status = row.get("status")
            if status in ("done", "error", "missing", "duplicate"):
                pending.discard(row["requestId"])
                results.append(row)
        if pending:
            time.sleep(3)
    return results

if __name__ == "__main__":
    matches = search_contacts()
    ids = [row["searchResultId"] for row in matches[:5]]
    print(f"Researching {len(ids)} contacts...")
    request_ids = research_contacts(ids)
    completed = poll_until_done(request_ids)
    for row in completed:
        contact = row.get("contact") or {}
        print(contact.get("fullName"), contact.get("email"), row["status"])
```

## Tips

* Use `supplementalData.nextToken` from search when you need more than one page — see [Search contacts](/searchcontacts).
* Watch `X-PublicAPI-Credits` — see [Rate limits and credits](/rate-limits-and-credits).
* For push delivery, see [Real-time enrichment with webhooks](/use-cases/real-time-enrichment-with-webhooks).

## Related help

* [Seamless Knowledge Base](https://seamless.ai/customers/education) — in-app search and list building
