Prospecting by hand goes like this: you get a list of company websites, open each one, check whether it's already in the CRM, find the right people, read up on what the company actually does, and then write an email that doesn't sound like a template. Repeat a few hundred times.
None of these steps is hard. All of them are slow. That makes the job a good fit for automation, as long as the final output still reads like a person did the research.
The stack at a glance
| Layer | What I used |
|---|---|
| Backend | Python, FastAPI |
| Front end | React |
| CRM | HubSpot API |
| People search | Apollo |
| Research | OpenAI deep research, other LLMs via OpenRouter |
| Data store | Directus (headless CMS over a database), MongoDB, Redis |
| Workflows | n8n |
| Deployment | Docker Compose |
The workflow
- Import. Paste URLs or upload a file.
- De-duplicate against the CRM. Check HubSpot first so nobody gets prospected twice.
- Find the people. Search for decision-makers by configurable target personas, not "everyone at the company".
- Research. An AI deep-research step reads up on the company and writes a structured brief: what they do, recent signals, likely pain points.
- Draft. An email generator writes outreach grounded in that brief and in a knowledge base of our own case studies, so every claim maps to something real.
- Review. A person approves the draft before anything is sent.
Grounding is what makes the output usable
Raw LLM-written outreach is easy to spot: generic praise, invented details, the same three opening lines. What fixed that wasn't a cleverer prompt. It was grounding:
- The research brief means the model writes from facts about this company.
- The knowledge base means the model talks about our work using real material, not made-up capabilities.
- A review UI keeps a human in charge of the final send.
I also built a feedback step that analyses responses, so the prompts improve based on what actually got replies instead of what I assumed would.
Clean data is boring and it matters
The least glamorous part made the most difference: CRM hygiene. I wrote export and analysis scripts plus an n8n workflow to flag accounts with no recent activity and forecast which ones were going cold. Agents working from a messy CRM just produce mistakes faster.
What I took away
- Automate the steps, keep the judgement. Humans review. Agents prepare.
- Ground every generation. A research brief and a knowledge base beat any prompt trick.
- Fix the data before adding AI. Automation magnifies whatever state your CRM is in.