Dock
Sign in & remix
REMIX PREVIEWTemplate

Outbound prospect research and sequence agent

Takes a weekly CSV of target accounts, researches each via web search and contact enrichment, drafts a personalized 3-step email sequence, and loads the rep's pipeline before Monday's standup.

· 13 min read· from trydock.ai

Agent: read this first

You're working in the Outbound prospect research and sequence agent workspace at trydock.ai/<org>/outbound-prospect-research-agent.

## Your role

Reads prospects.csv every Monday at 7 AM, runs web research + Apollo enrichment per account, drafts a 3-step email sequence per prospect, creates CRM contact, writes one Prospects row per account. Skips already-processed companies via processed.json. Never sends an email on its own.

## Cadence, when to update Dock

- After EVERY tool call that changes state (row create / update, doc append), append an entry to the **Status** surface.
- After every milestone, update the canonical doc surface for that work.
- When you start a session, READ the last 5 Status entries first to know what happened since you last worked.

## User-loop protocol

- End EVERY reply to the user with: "Check Dock for the latest at trydock.ai/<org>/outbound-prospect-research-agent."
- If you make a decision the user might want to override (priority, scope cut, tone change), append to **Status** AND mention it in your reply: "Decided X. If you'd rather Y, edit [surface] and I'll re-plan."
- If you're blocked, post to Status with prefix `BLOCKED:` and ask one specific question.

## Don't touch

- Canonical phase / column / surface titles.
- Anything in a section titled "Locked" or "Decisions sealed."
- The agentPrompt itself (this section).

## First tool calls

1. `list_surfaces(workspace_slug="outbound-prospect-research-agent")`
2. `get_doc(workspace_slug="outbound-prospect-research-agent", surface_slug="status")`
3. `list_rows(workspace_slug="outbound-prospect-research-agent", surface_slug="prospects")`

---

# Outbound prospect research and sequence agent

A weekly agent-automated batch. Drop a CSV on Friday, get 20 researched sequences Monday morning. Open in Dock and you get four surfaces seeded:

- **Prospects** (table) one row per researched prospect: Company, Contact, Email, Email Status, Title, LinkedIn, Status, Research Notes, Email 1 / 2 / 3 (subject + body), CRM ID, Added.
- **Setup guide** (doc) how the agent connects to Brave Search + Apollo + the CRM + the Python recipe for the weekly batch.
- **Activity log** (doc) running narrative log of every batch run: companies processed, skipped, failed, with the agent's research notes.
- **Status** (doc) the agent's working session log. End of every batch: 1 paragraph of what was processed, what was skipped.

## Bring your own agent

Connect one agent to this workspace (Claude in Cursor, Claude Code, Codex, any MCP client). The agent runs every Monday at 7 AM against prospects.csv, no manual trigger needed once the cron is wired.

## The user-loop protocol

Your agent proposes; you decide.

- Friday: rep adds 10-30 target companies to prospects.csv. Required column: company. Optional: contact_name, contact_email, title.
- Monday 7 AM: agent reads prospects.csv, skips already-processed rows (processed.json), researches each remaining company via Brave Search, enriches via Apollo, drafts a 3-step personalized email sequence via Claude, creates the CRM contact, writes one Prospects row.
- Agent NEVER sends an email. Every sequence lands in the Prospects row as draft text; the rep reviews, edits, and sends from their own email client.
- Agent NEVER edits a Prospects row once the rep has updated Status past Researched (Queued, Sent, Replied, Meeting Booked, Passed are rep-controlled).
- End of every batch, agent writes 1 paragraph to **Status**: companies processed, skipped (already done), failed, next Monday's batch size.

## First run

1. Confirm CRM + research tools with the operator. HubSpot + Brave Search + Apollo is the default; Salesforce / Pipedrive are documented in Setup guide.
2. Confirm legal compliance: CAN-SPAM physical address + unsubscribe link, GDPR legitimate-interest basis for any EU prospects. The agent inserts placeholders; the rep fills them before sending.
3. Open Setup guide and follow the install steps. Configure .env with all the keys.
4. Add 3-5 test prospects to prospects.csv. Run python prospect_sequence.py prospects.csv once. Confirm Prospects + Activity log + Status all populated.

## Status

### [00:00 UTC] seeded by Dock
Workspace created from the outbound prospect research and sequence agent template. Agent: read the Setup guide, then confirm CRM + Brave + Apollo + Anthropic + compliance posture with the operator before the first batch.
Next: confirm tools + compliance.

Outcome

A weekly agent-automated outbound batch where 10-30 researched prospects, personalized 3-step sequences, and CRM contacts all land in Dock + the CRM before Monday standup, with the rep reviewing and sending from their own email client.

Estimated time: 60 min setup, ongoing ~15 min/week to drop the CSV + review drafts
Difficulty: beginner
For: Founders, sales reps, and ops leads at $5M-$50M revenue companies running outbound weekly.

What you'll need

Pre-register or install before you start.

  • Dock (Free plan covers this template; Pro $19/mo unlocks more workspaces.) — The workspace itself, the Prospects pipeline table, the Activity log doc surface, the Status surface.
  • Anthropic API (Pay per token, ~$0.03-$0.10 per prospect.) — Claude runs the per-prospect research synthesis and drafts the 3-step sequence.
  • Brave Search API (Free tier 2,000 queries/month; ~3 queries per prospect.) — Web research per company. Funding, recent news, leadership team, product overview.
  • Apollo.io (optional) (Free tier 50 credits/month; paid plans from $49/user/mo.) — Contact enrichment: name + company yields a verified email when Apollo has coverage. 40-60% match rate on typical B2B lists.
  • HubSpot / Salesforce / Pipedrive API (Free with existing CRM seat.) — Create the prospect contact (so the rep can log activity later). Script handles 409 conflicts by extracting the existing contact ID, no duplicates.
  • CueAPI (optional) (Free tier covers weekly cadence.) — Cloud-scheduled weekly run so Monday 7 AM batches keep firing when your laptop is closed.

The template · 5 steps

Step 1: Confirm CRM + research tools + compliance posture

Estimated time: 10 min

Three decisions up front: which CRM, which research tools (Brave is required; Apollo is recommended but optional), and the legal compliance posture for cold outbound. CAN-SPAM applies to US prospects; GDPR applies to EU prospects. The agent inserts placeholders; the rep fills them.

Tasks

  • Ask which CRM. HubSpot + Salesforce + Pipedrive paths documented; script defaults to HubSpot.
  • Generate CRM token. HubSpot Private App scopes: crm.objects.contacts.read + write, crm.objects.companies.read.
  • Sign up for a free Brave Search API key at brave.com/search/api. 2,000 free queries/month covers ~600 prospects.
  • Optional: sign up for Apollo.io free tier (50 credits/month). One credit per enrichment.
  • Confirm with the operator: physical mailing address for the email footer + unsubscribe URL pattern. Both go into placeholders the rep fills before sending.

[!CAUTION] Gotchas

  • Apollo coverage. Best for US companies with 50+ employees. Small private companies often return guessed or unavailable. The script flags those so the rep manually finds the contact.
  • GDPR. If targeting EU prospects, confirm legal basis (typically B2B legitimate interest) with the operator's legal team before launching. The agent will not block on this, but the operator owns the call.
  • LinkedIn scraping is not in this template. Automated LinkedIn scraping violates LinkedIn's ToS. LinkedIn Sales Navigator CSV exports are a valid manual input.

Step 2: Wire .env + the Python script

Estimated time: 25 min

One script: prospect_sequence.py runs every Monday at 7 AM against prospects.csv. Idempotent via processed.json: re-running the same CSV after a partial failure skips already-done companies. Handles Brave quota exhaustion gracefully (continues with generic sequences for remaining prospects).

Tasks

  • Open Setup guide (doc) and copy prospect_sequence.py into a local folder
  • Run pip install anthropic requests python-dotenv
  • Create .env with DOCK_API_KEY, DOCK_WORKSPACE_SLUG, ANTHROPIC_API_KEY, HUBSPOT_ACCESS_TOKEN, BRAVE_API_KEY, APOLLO_API_KEY (optional), REP_NAME, REP_COMPANY, REP_TITLE, CLAUDE_MODEL=claude-sonnet-4-6
  • Generate a Dock API key at trydock.ai/settings/api
  • Set up the Prospects table column schema explicitly before the first run (see Setup guide doc for the full column list).

[!CAUTION] Gotchas

  • Column schema. Dock auto-creates columns the first time the script writes a row, but auto-created columns are unordered and untyped. Always set the schema explicitly first.
  • processed.json is the de-dup file. Don't delete it. If you do, the next run re-processes every company in prospects.csv (research costs + API quota).

Step 3: Test with 3-5 prospects (manual run)

Estimated time: 20 min

Before scheduling, run a small test batch. This confirms research quality, sequence personalization, and CRM contact creation all work. The rep reviews the first 3-5 drafts and gives the agent feedback before going to weekly scale.

Tasks

  • Create test_prospects.csv with 3-5 companies you know well
  • Run python prospect_sequence.py test_prospects.csv
  • Open Prospects (table). Confirm one row per company with Research Notes + three email drafts populated.
  • Walk through with a rep: does the research summary sound right? Do the emails sound like the rep? If not, edit REP_NAME / REP_COMPANY / REP_TITLE and the prompt in generate_sequence().
  • Re-run the same CSV. Confirm all 3-5 companies are skipped (de-duplication via processed.json works).

[!CAUTION] Gotchas

  • Research quality. Small private companies with limited web presence will produce generic sequences. The script flags this in Research Notes: 'No public information found.' Those need manual research.
  • Email tone. Default prompt avoids 'I hope this finds you well' and buzzwords. If the drafts still sound generic, paste 2-3 examples of the rep's actual cold emails into the prompt as few-shot examples.

Agent prompt for this step

Run a first batch through test_prospects.csv. Load processed.json. For each row whose company is not in processed.json: research_prospect() via Brave Search (3 queries: company overview, leadership, contact). apollo_enrich() if APOLLO_KEY is set. generate_sequence() via Claude (3 emails with [PHYSICAL_ADDRESS] + [UNSUBSCRIBE_LINK] placeholders). create_hubspot_contact() (handle 409 by extracting existing ID). write_to_dock_table() with all fields. Append company to processed.json. Post a Status entry: processed, skipped, failed.

Step 4: Schedule the Monday 7 AM batch

Estimated time: 10 min

Once test batch quality is good, schedule the weekly run. The rep drops new companies into prospects.csv each Friday; Monday 7 AM the agent processes them; by 9 AM standup the rep has the sequences loaded.

Tasks

  • Option A, cron: crontab -e, add 0 7 * * 1 cd /path && source .env && python3 prospect_sequence.py weekly_prospects.csv >> outbound.log 2>&1
  • Option B, CueAPI: cueapi create --schedule '0 7 * * 1' --name 'outbound-prospect-research' --handler ./prospect_sequence.py
  • Set a calendar reminder for the rep: every Friday by 5 PM, add 10-30 target companies to prospects.csv. Required column: company. Optional: contact_name, contact_email, title.
  • Confirm next Monday: Status has a fresh session entry + Prospects has new rows + Activity log has a new batch summary section.

[!CAUTION] Gotchas

  • Brave Search quota. Free tier is 2,000 queries/month, ~3 queries per prospect. At 30 prospects/week that's ~360/month, well inside the cap. If batch sizes balloon to 100+/week, upgrade.
  • Apollo credits. Free tier is 50 credits/month. At 30 prospects/week without re-enriching, that's ~120/month - over the cap by week 2. Either upgrade Apollo or skip enrichment for some prospects.

Step 5: Make the Friday-add + Monday-review the rep ritual

Estimated time: 5 min one-time

The whole flow only works if reps add to prospects.csv on Friday and review the drafts on Monday. Pin the Prospects URL into the sales channel + make the Monday review the first 15 minutes of standup.

Tasks

  • Pin the Prospects table URL (trydock.ai/[org]/outbound-prospect-research-agent/prospects) to the sales Slack channel
  • Block 15 min on the rep's calendar every Monday at 9 AM: review the new Prospects rows. For each: fill [PHYSICAL_ADDRESS] + [UNSUBSCRIBE_LINK], optionally tweak the personalization, set Status=Queued, send Email 1.
  • Move the row through the rep-controlled Status values as the sequence plays out: Queued, Sent, Replied, Meeting Booked, Passed.

[!CAUTION] Gotchas

  • If the rep doesn't review on Monday, the drafts pile up + the rep loses the rhythm. Pin the URL in two places (channel + calendar event) so the link is unmissable.
  • Status values are rep-controlled. The agent only writes Status=Researched on first creation; everything after is the rep's call.

Hand the template to your agent

Paste the prompt below into your agent's permanent system prompt so the agent reads, writes, and maintains this workspace as you work through the steps.

You are the agent running on the "Outbound prospect research and sequence agent" template workspace, connected via MCP at your-org/outbound-prospect-research-agent.

Your job: every Monday at 7 AM, process prospects.csv. For each unprocessed company: research via Brave Search, enrich via Apollo, draft a personalized 3-step email sequence via Claude, create the CRM contact, write one Prospects row. Never send an email.

User-loop protocol:
- You propose. The rep decides. Never send an email; never edit a Prospects row past the Researched stage (Queued, Sent, Replied, Meeting Booked, Passed are rep-controlled).
- Monday 7 AM (or "run outbound batch"): load processed.json. For each row in prospects.csv whose company is not in processed.json: research_prospect() via Brave Search, apollo_enrich() if APOLLO_KEY is set, generate_sequence() via Claude, create_hubspot_contact(), write_to_dock_table(). Append company to processed.json.
- Compliance: every sequence the agent drafts MUST include [PHYSICAL_ADDRESS] and [UNSUBSCRIBE_LINK] placeholders for the rep to fill before sending. Never strip those placeholders. Never auto-fill them with guesses.
- Apollo email status: only sequences where Apollo returned email_status=verified should be marked Status=Researched. Sequences with guessed or unavailable emails get Status=Needs Email so the rep manually finds the contact.
- End of every batch, write 1 paragraph to Status: companies processed, skipped (already done), failed, next Monday's batch size, any Brave or Apollo quota warnings.

Don't touch:
- processed.json from a prior run (never delete the file; only append).
- Prospects rows older than this run where Status != Researched (rep moved them past initial research).
- The [PHYSICAL_ADDRESS] / [UNSUBSCRIBE_LINK] placeholders in any sequence draft.

First MCP tool calls:
1. list_surfaces(workspace_slug="outbound-prospect-research-agent")
2. list_rows(workspace_slug="outbound-prospect-research-agent", surface_slug="prospects")
3. get_doc(workspace_slug="outbound-prospect-research-agent", surface_slug="status")

FAQ

How is this different from the /templates/run-a-cold-email-outreach-sprint playbook?

The cold-email-sprint is a one-time human-driven push: pick 50 targets, write your own sequences, send over 3 weeks. This template is the agent-automated weekly batch version: drop a CSV every Friday, agent runs Monday 7 AM, sequences load themselves. They sit alongside, not in competition.

Does the agent send emails on its own?

No. Every email is drafted into the Prospects row with [PHYSICAL_ADDRESS] and [UNSUBSCRIBE_LINK] placeholders. The rep reviews, edits, fills placeholders, and sends from their own email client. The agent never controls the rep's email account.

What if Apollo can't find a verified email?

The Email Status column on the Prospects row shows verified, guessed, or unavailable. The agent draft still lands (the rep can manually find the contact). Status=Researched only on verified; Status=Needs Email on the others so the rep knows to look.

Can I re-run the same CSV without re-processing everything?

Yes. processed.json tracks which companies have already been done. Re-running the same CSV skips them automatically. Delete processed.json only if you want a full re-run (which costs API quota).

Does this work with Salesforce / Pipedrive instead of HubSpot?

Yes with code edits. Default script targets HubSpot v3 CRM API. The Extending section in Setup guide shows the simple-salesforce + pipedrive swaps. The research + sequence generation parts don't change; only create_*_contact() swaps out.

Remix this into Dock

Make this yours. Edit, extend, run agents on it.

Sign in (free, 20 workspaces) — Dock mints a copy of this in your own workspace. The original stays untouched.

No Dock account? Sign-in is signup. Magic-link in 30 seconds.