---
name: instagram-coach-research
description: Find German-speaking Swiss coaches on Instagram, build a research shortlist CSV, generate DM drafts, and track outreach
---

# /instagram-coach-research Workflow

Builds a qualified shortlist of German-speaking Swiss coaches found via Instagram, saves them to a CSV, generates two-tier DM messages, and tracks the full outreach lifecycle — from discovery through reply and follow-up.

---

## 🗺️ Full User Story

1. We need coaches to sign up on bondigoo.ch before launch (März 2026) to avoid a "ghost town" effect.
2. Prio 1 email outreach showed most established coaches are fully booked → not our best audience.
3. Instagram shows us coaches who are **posting actively but not breaking through** → they need better discoverability → they are our ideal early adopters.
4. We reach out from the **bondigoo Instagram account** (@bondigoo).
5. We **build a shortlist first**, review it together, then send DMs manually — no automation.
6. Two tiers:
   - **Founding Coach** (1000+ followers, high quality): ask for feedback on the platform
   - **Standard reach-out** (50–999 followers): ask them to check out bondigoo.ch

### 🎯 Phase 2 Targeting Shift (March 2026)

> [!IMPORTANT]
> **Traditional, established coaches react negatively to bondigoo.** They are protective of their titles, certifications, and professional standing. They see a Fiverr-like open marketplace as a threat — associating it with "self-proclaimed coaches" diluting their profession.

**Phase 1 evidence:**
- ❌ Christiane Kosub (ICF PCC, 30yr): Declined — quality standards concern
- ❌ Pirmin Loetscher, Esther Gygax: Polite decline — fully booked, no interest
- ✅ **Fabian Lüthi** (mental coach, ex-ice hockey): **Positive call** — open to knowledge transfer

**Conclusion:** Target "knowledge-sharers" — mentors, trainers, creators, career-pivoters who want to teach and scale — NOT traditional certified coaches who guard their title.

**The ideal bondigoo coach:**
- Sees themselves as a **teacher, mentor, or guide** — not exclusively as a "certified coach"
- Wants to **scale their impact** beyond 1:1 (digital programs, group sessions, courses)
- Is **digitally native or digitally curious** — active on IG/YouTube, creates content
- Has a **non-traditional background** — career pivoters, athletes, entrepreneurs, creators
- Values **visibility and discoverability** over gatekeeping
- Is **not fully booked** — has capacity and ambition to grow

**The anti-pattern (skip or deprioritize):**
- ICF/BSO-certified purists who see coaching as a protected profession
- Heavy academic positioning (Dr., lic., Prof.) with "Sie"-Form website
- Coaches > 55 with 20+ year practice and no digital presence
- Anyone whose website reads like a clinical practice

---

## ⚙️ Configuration

| Setting | Value |
|---|---|
| Target language | German (posts in German) |
| Target geography | German-speaking CH: Zürich, Bern, Basel, Luzern, St. Gallen, Zug, Aarau, Winterthur, Schaffhausen, Thurgau, or "Schweiz"/"CH" in bio |
| Min followers | 50 |
| Max followers | 5000 |
| Min posts | 5 |
| Max inactivity | 3 months since last post |
| Outreach account | @bondigoo (bondigoo Instagram) |
| DM language | German, Du-Form |
| CSV output | `Coach_Data/instagram_outreach.csv` |

---

## ⚠️ Rules (Always Apply)

- **NEVER contact anyone during the research phase.** No DMs, no likes, no follows, no comments.
- All DMs are composed and reviewed by the user before sending.
- Max **10–15 DMs per day** once outreach begins (Instagram spam flag risk).
- No links in the first DM message.
- Du-Form throughout (Instagram is casual).
- Short messages only — max 3–4 sentences.

---

## 📄 CSV Format

File: `Coach_Data/instagram_outreach.csv` (semicolon-delimited, UTF-8)

### Columns

| Column | Description |
|---|---|
| `profile_url` | Full URL: https://www.instagram.com/username/ |
| `username` | @handle |
| `display_name` | Name shown on profile |
| `followers` | Approximate follower count as shown |
| `following` | Who they follow |
| `posts_count` | Number of posts |
| `bio` | Full bio text |
| `location_in_bio` | City or "Schweiz" mention |
| `link_in_bio` | Website URL if present |
| `niche` | Coaching niche (e.g. Business, Life, Career, Leadership, Mental, Burnout, Executive, Team, Sport, Relationship) |
| `posts_in_german` | yes/no |
| `content_quality` | low/medium/high |
| `last_post_approx` | e.g. "2 days ago", "1 week", "1 month" |
| `founding_coach_potential` | yes/no |
| `founding_coach_reason` | Why yes or no |
| `dm_hook` | One specific personalization detail for the DM |
| `dm_tier` | founding / standard |
| `dm_drafted` | yes/no |
| `dm_sent` | yes/no |
| `dm_sent_date` | Date sent (DD.MM.YYYY) |
| `reply_received` | yes/no |
| `reply_date` | Date of reply |
| `reply_sentiment` | positive/neutral/negative/bounced |
| `outcome` | e.g. signed_up / interested / declined / no_reply / follow_up_needed |
| `notes` | Any free-text notes |
| `date_added` | Date profile was added (DD.MM.YYYY) |
| `source_hashtag` | Which hashtag led to this profile |
| `knowledge_sharer_score` | **1–5 rating** (see scoring rubric below) |
| `outreach_angle` | **Classification** of which bondigoo value prop to highlight: `visibility` / `digital_scaling` / `business_in_a_box` / `community` / `credibility` / `niche_monopoly` |
| `recommended_priority` | **1–5** (1=contact first, 5=deprioritize). Based on knowledge_sharer_score + outreach_angle + founding potential |

### Knowledge-Sharer Score Rubric

| Score | Profile | Key Signals |
|-------|---------|-------------|
| 5 | **Creator-Coach** | Sells courses/digital products, podcast/YouTube, positions as teacher/mentor |
| 4 | **Hybrid Coach** | Workshops + 1:1, active IG, career-pivot background, content creator |
| 3 | **Neutral** | Standard coach, some digital presence, unclear marketplace openness |
| 2 | **Traditional-leaning** | Formal website, heavy credentials, "Sie"-Form, limited digital |
| 1 | **Gatekeeper** | ICF/bso purist, clinical positioning, opposes open marketplace |

### Outreach Angle Categories

| Angle | When to Use | Lead With |
|-------|-------------|----------|
| `visibility` | Low followers but good content, struggles with discoverability | "Kunden finden DICH aktiv" |
| `digital_scaling` | Already teaches offline, wants courses/programs | "Online-Kurse, Live-Sessions, Programme" |
| `business_in_a_box` | No/basic website, manual booking | "Alles-in-einem: Buchung, Zahlung, Profil" |
| `community` | Values peer networks, early-adopter | "Teil der Gründer-Community werden" |
| `credibility` | No traditional certs, needs social proof | "Bewertungen und Ratings statt Zertifikate" |
| `niche_monopoly` | Unique niche not yet on bondigoo | "Diese Nische gibt es bei uns noch nicht" |

---

## 📋 Steps

### Step 0 — Pre-flight check
// turbo
Check if `Coach_Data/instagram_outreach.csv` already exists.
- If yes: read existing records, show count, continue adding new ones (skip duplicates by `username`)
- If no: create the file with the header row above

```powershell
# Check if CSV exists
Test-Path "Coach_Data/instagram_outreach.csv"
```

### Step 1 — Open Browser & Verify Login

Open a browser subagent to https://www.instagram.com

If a login screen appears: **STOP and notify the user** to log in with the bondigoo account (@bondigoo), then wait for confirmation before continuing. Login credentials are saved in the browser.

Once logged in, confirm the active account is the bondigoo account.

### Step 2 — Parallel Research Sweep (DO THIS IN PARALLEL)

> 🚀 **KEY PRINCIPLE**: Launch **3 browser subagents simultaneously** and **multiple `read_url_content` calls** at the same time. Never visit profiles one-by-one with a single browser agent — that is 3–5x slower.

#### 2a — Batch Username Extraction (in each browser subagent)

Instead of clicking through individual posts, use this **JavaScript batch extraction technique** on each hashtag page:

```javascript
// Run this in execute_browser_javascript on every hashtag page:
(() => {
  const posts = Array.from(document.querySelectorAll('a[href*="/p/"]')).map(a => a.href);
  const imgs = Array.from(document.querySelectorAll('img[alt]')).map(i => i.alt);
  return JSON.stringify({ posts: [...new Set(posts)], imgs });
})()
```

This returns 20+ candidate usernames per hashtag page in one step. Then navigate to profiles directly:
```
https://www.instagram.com/[username]/
```

Skip immediately if follower count is outside 50–5000 range — don't read bio or posts.

#### 2b — Hashtag Groups (Assign Each to a Separate Browser Subagent)

**Group A — City hashtags** (highest hit rate for Swiss coaches):
```
#coachzürich  →  /explore/search/keyword/?q=%23coachzürich
#coachbern    →  /explore/search/keyword/?q=%23coachbern
#coachbasel   →  /explore/search/keyword/?q=%23coachbasel
#coachstgallen → /explore/search/keyword/?q=%23coachstgallen
#coachingsolothurn → /explore/search/keyword/?q=%23coachingsolothurn
#coachingwinterthur → /explore/search/keyword/?q=%23coachingwinterthur
#coachaargau  →  /explore/search/keyword/?q=%23coachaargau
#coachthurgau →  /explore/search/keyword/?q=%23coachthurgau
```

**Group B — Niche hashtags**:
```
#hypnosecoach
#nlpcoach
#beziehungscoach
#trennungscoach
#frauencoaching
#ernährungscoach
#familiencoach
#systemischescoaching
#traumacoach
```

**Group C — Mindset/development hashtags**:
```
#selbstentwicklung
#resilienz
#mentalesstärke
#achtsamkeit
#karriereberatung
#businessmentor
#worklifebalance
#empowerment
#führungscoaching
#burnoutcoach
```

**Group D — Primary broad hashtags**:
```
#coachingschweiz
#businesscoachschweiz
#lifecoachschweiz
#karrierecoach
#mentalcoach
#gesundheitscoaching
#executivecoach
#lebensberatung
#persönlichkeitsentwicklung
```

**Group E — Creator/Mentor hashtags** (Phase 2 — highest priority):
```
#onlinekurs #onlinekurserstellen
#mentoring #mentorschweiz
#workshopschweiz #retreatschweiz
#coachingbusiness #coachwerden
#sichtbarkeit #onlinesichtbarkeit
#digitalcoach #onlinecoaching
```

**Group F — Niche knowledge-transfer hashtags** (Phase 2):
```
#finanzcoach #nutritioncoach
#fitnesstrainer #personaltrainer
#yogalehrerin #yogateacher
#atemarbeit #breathwork
#meditationslehrer #meditationschweiz
#sprachcoach #stimmcoach #rhetorikcoach
#hundetrainer #tiercoach
#lerncoach #elterncoach #mamacoach
```

**Group G — Lifestyle/authority-building hashtags** (Phase 2):
```
#schweizerblogger #swissblogger
#selbstständigschweiz #gründenschweiz
#contentcreatorschweiz
#podcastschweiz
#speakerschweiz
```

⚠️ **Use `/explore/search/keyword/?q=%23[hashtag]`** — NOT `/explore/tags/[hashtag]/`. The keyword URL loads more reliably.

**Phase 2 priority:** E > F > G > A > B > C > D (creator/mentor hashtags first, traditional coaching hashtags last).

#### 2c — Similar Accounts Discovery (run as 4th browser subagent)

For every **Founding Coach** (1000+ followers) already in the CSV:
1. Open their profile
2. Click the "Similar accounts" button (appears below the Follow button)
3. Visit each suggested profile
4. Evaluate with normal criteria

This approach yields high-quality, algorithm-matched Swiss coaches. **The more Founding Coaches in your CSV, the more effective this becomes.**

#### 2d — Parallel Technical Setup

Start these **simultaneously** (call all browser subagents in a single tool call block):

```
browser_subagent #1: Group A (city hashtags)
browser_subagent #2: Group B (niche hashtags)  
browser_subagent #3: Group C (mindset hashtags)
browser_subagent #4 (optional): Similar accounts from Founding Coaches
```

Each subagent should open 2–3 browser pages internally to scan multiple hashtag pages in parallel before visiting profiles.

---

#### 2e — ⚡ FAST PATH (Recommended — use this by default)

> **Two-phase design. Phase 1 always. Phase 2 only if needed.**

**Key insight:** Google `search_web` results alone are sufficient to decide *contact / no-contact*. You get handle, follower count, bio snippet, city, and language directly from SERP snippets. **Do not add enrichment steps unless the user explicitly asks.**

##### Phase 1 — Harvest & Write (~5 min for 60–100 records)

1. Fire **25–30 `search_web` queries in a single parallel block** (all at once, not sequentially):

```
# City queries (highest Swiss specificity):
"coach zürich instagram @" OR "coaching zürich instagram bio 2025"
"coach bern instagram @" OR "coaching bern instagram profil"
"coach basel instagram handle deutschsprachig"
"coach luzern instagram schweiz bio"
"coach st.gallen instagram"
"coach winterthur instagram coaching"
"coach zug instagram profil"
"coach aarau instagram"
"coach schaffhausen instagram"
"coach solothurn instagram"

# Niche queries:
"ernährungscoach schweiz instagram"
"hypnosecoach schweiz instagram"
"frauencoaching schweiz instagram"
"beziehungscoach schweiz instagram"
"karrierecoach zürich bern instagram"
"mindset coach schweiz instagram"
"traumacoach schweiz instagram"
"führungscoach schweiz instagram"
"burnoutcoach schweiz instagram"
"elterncoach schweiz instagram"
"sportmentalcoach schweiz instagram"
"businesscoach zürich instagram"
"mentaltraining schweiz instagram"
"systemischer coach schweiz instagram"
"paarberatung schweiz instagram"
```

2. From every search result, extract any **@handle** directly visible in the snippet or URL.
3. For every handle found, immediately fire **`read_url_content("https://www.instagram.com/[handle]/")`** in parallel to get:
   - Exact follower/following/post counts from OG meta: `"X Followers, Y Following, Z Posts"`
   - Drop if followers < 50 or > 5000, or posts < 5
4. **Write all passing records to CSV immediately** — do not wait for bio collection.

Record these fields from what you already have:
- `username`, `followers`, `following`, `posts_count` (from OG tag)
- `display_name` (from OG title)
- `bio` = "(to be enriched)" or whatever snippet Google showed
- `location_in_bio` = infer from search query city if not yet known
- `niche` = infer from bio snippet
- `posts_in_german` = infer from language of snippet
- `dm_hook` = generate from bio snippet (good enough for initial triage)
- `content_quality` = "unknown" until enriched
- `last_post_approx` = "unknown" until enriched

**Expected: 60–100 CSV records written in under 5 minutes.**

##### Phase 2 — Optional Enrichment (only if user requests DM personalization)

Only run this for records where:
- `founding_coach_potential = YES` (you want a personalized opening)
- OR `bio = "(to be enriched)"` and you need the actual bio for the DM

For targeted enrichment of specific usernames:
1. Fire `browser_subagent` with a batch of 10–15 profiles
2. Collect: bio, location, last post date, one DM hook detail
3. Update CSV records

**Do NOT run Phase 2 automatically.** Ask user first: *"Soll ich die Bios für die Founding Coach Kandidaten noch anreichern?"*

---

##### Hard Lessons from Sprint (21.02.2026) — What Slowed Us Down

- ❌ **Sequential pipeline**: harvest → validate → enrich → write = slow. Do everything in one pass.
- ❌ **Bio collection before CSV write**: wasted 15+ min on browser work before a single record was saved.
- ❌ **Treating OG-tag read as separate validation step**: you already know from search_web if a handle is real; skip the intermediate OG-tag read and just write the record.
- ❌ **Launching browser subagents for discovery AND bio in same sprint**: discovery via hashtags is unpredictable and slow; stick to `search_web` + website scraping for discovery.
- ✅ **`search_web` SERP snippets often contain enough bio data**: follower count, city, niche, language — sufficient for a contact decision.
- ✅ **Write raw records, enrich later**: a record with `bio = "(to be enriched)"` in the CSV is infinitely more useful than a perfect record still in the agent's memory.
- ✅ **Target: 1 record per 3 seconds in Phase 1** — if slower than this, you're enriching too early.

This is a fundamentally faster 3-phase architecture. **Use this instead of 2a–2d when you need 100+ records quickly.**

**Key breakthrough:** `read_url_content("https://www.instagram.com/[username]/")` returns follower/following/post counts from public OG meta tags — **no login required**:
```
OG Description: "2,809 Followers, 490 Following, 260 Posts - See Instagram..."
```
This eliminates the browser for Phase 2 follower filtering.

##### Fast Phase 1 — Parallel Username Harvest (~60 sec)
Fire **25+ `search_web` queries simultaneously**, each targeting a different city/niche combo:
```
city queries:  "coach zürich instagram deutsch bio 2025"
               "coach bern instagram handle schweiz"
               "coach basel instagram profil deutschsprachig"
               "coach luzern instagram schweiz"
               "coach st.gallen instagram handle"
               "coach winterthur instagram coaching"
               "coach zug instagram profil deutsch"
               "coach aarau instagram coaching"
               "coach schaffhausen instagram"
               "coach solothurn instagram bio"
niche queries: "ernährungscoach schweiz instagram handle"
               "hypnosecoach schweiz instagram profil"
               "frauencoaching schweiz instagram"
               "beziehungscoach schweiz instagram"
               "familiencoach schweiz instagram"
               "karrierecoach zürich bern instagram"
               "mindset coach schweiz instagram"
               "traumacoach schweiz instagram"
               "führungscoach schweiz instagram"
               "sportmentalcoach schweiz instagram"
creative:      "'ich bin coach' OR 'als coach' zürich bern instagram 2025"
               "coaching blog schweiz instagram 'folge mir'"
               "business coach schweiz instagram -agentur -schule"
               "mentaltraining schweiz instagram profil"
               "systemischer coach schweiz instagram 2025"
```
Expected: 150–300 raw usernames after dedup.

##### Fast Phase 2a — Bulk Follower Filter (~20 sec)
For every candidate username, fire `read_url_content("https://www.instagram.com/[username]/")` **all simultaneously**.
Parse: `OG Description: "X Followers, Y Following, Z Posts"`
Drop immediately if: X < 50 or X > 5000 or Z < 5.
Expected: ~30–40% pass → 60–100 qualified.

##### Fast Phase 2b — Bio Collection (~3–4 min)
For the ~60–100 qualified profiles, run **6 browser subagents in parallel** (10–15 profiles each).
Each visits profiles directly, reads bio, location, language, last post, generates dm_hook.
Expected total time: **6–8 minutes end-to-end for 80–130 qualifying records.**

##### Future Options (even faster, not yet used):
- **Path B** — Local Puppeteer script: 10 headless browsers in parallel, ~2 min for 150+ profiles. Requires Instagram session cookie export.
- **Path C** — `search_web("[username] instagram")` to get Google-cached bio text without browser (faster but bio quality varies).
- **Path Z** — Pure `node-fetch` script: 200 concurrent HTTP requests for OG data in ~60 sec (follower+name only, no bio).

### Step 3 — Profile Evaluation

For each post found in Step 2, click through to the author's profile and evaluate against these criteria:

**INCLUDE if:**
- 50–5000 followers
- 5+ posts
- Posts in German
- Bio or posts suggest Switzerland-based (see geography config above)
- Posted within the last 3 months
- **Phase 2 bonus signals (include even if borderline on other criteria):**
  - Positions as mentor, trainer, teacher — not just "Coach"
  - Creates educational content (tips, how-tos, explainers)
  - Offers or plans to offer workshops, retreats, courses, or group programs
  - Career-pivoter with unique background (ex-athlete, ex-corporate, ex-artist)
  - Uses "Du"-Form on profile — casual, approachable
  - Adjacent niche: dog trainer, vocal coach, fitness trainer, financial advisor, etc.

**SKIP if:**
- < 50 or > 5000 followers
- < 5 posts
- Posts NOT in German
- Clearly not Switzerland-based (e.g., Germany-only hashtags with no CH reference)
- Large coaching company or institute (not an individual coach)
- Last post > 3 months ago
- Already in the CSV (check by username)
- **Phase 2 skip signals (deprioritize or skip entirely):**
  - Heavy academic/clinical positioning (Dr., lic., Prof. as primary identity in bio)
  - Bio mentions ICF/BSO certification as THE defining feature
  - "Sie"-Form throughout website — signals traditional, formal style
  - Website reads like a clinical practice (appointment booking, Krankenkasse)
  - No digital presence beyond a static website
  - Dismissive of non-certified coaches in content

**Founding Coach Potential = YES if ALL of:**
- 1000+ followers
- Content quality = high
- Clear professional niche
- Posts consistently (at least 1x/week based on recent posts)
- **Phase 2 founding bonus signals (upgrade to YES even if followers slightly below 1000):**
  - Has or is developing digital products (courses, programs, memberships)
  - Runs a podcast, YouTube channel, or newsletter
  - Career-pivoter with a compelling personal story
  - High engagement rate (comments, shares) relative to follower count
  - Content shows teaching/education intent, not just personal branding

### Step 4 — Save to CSV

After visiting profiles in a batch of 5-10, append new records to `Coach_Data/instagram_outreach.csv`.

For each profile, generate the `dm_hook` field — ONE specific thing from their profile (a post topic, bio detail, content angle) that could personalize a DM. This is the most important field.

Set `dm_tier` automatically:
- `founding` if `founding_coach_potential = yes`
- `standard` if `founding_coach_potential = no`

Set `dm_drafted = no`, `dm_sent = no`, `date_added = [today DD.MM.YYYY]`.

**De-duplicate:** before appending, check if `username` already exists in the CSV.

### Step 5 — Show Summary

After research is complete, display:
- Total profiles found
- Breakdown: founding coach potential (yes/no)
- Breakdown by niche
- Breakdown by follower range (50–199, 200–499, 500–999, 1000–5000)
- List of hashtags searched
- How many new vs. skipped (duplicate) records

Ask user: "Möchtest du die DM-Entwürfe für diese Coaches generieren?"

### Step 6 — Generate DM Drafts

For each record where `dm_drafted = no`, generate the appropriate DM message:

#### 🔵 Founding Coach DM (`dm_tier = founding`)

```
Dein [dm_hook]. Ich baue gerade bondigoo, eine Schweizer Plattform wo du dein Wissen mit Online-Kursen, Live-Sessions und Coachings teilen kannst. Wir suchen noch 2–3 Gründer-Coaches, die uns früh Feedback geben. Wäre das spannend für dich?
```

Rules:
- Replace `[dm_hook]` with a specific, personal observation
- No emojis
- No link
- Ends with a question

#### 🟢 Standard Reach-out DM (`dm_tier = standard`)

```
Dein [dm_hook]. Ich baue gerade bondigoo, eine Schweizer Plattform wo du dein Wissen mit Kursen, Live-Sessions und Coachings teilen und verkaufen kannst. Wir launchen im März. Magst du kurz reinschauen? → bondigoo.ch
```

Rules:
- Replace `[dm_hook]` with a specific, personal observation
- Max one emoji (optional, at end)
- One link allowed (bondigoo.ch) — only at end, not at start

#### DM Hook Formula (for both tiers)
> Specific content detail or bio observation → brief personal reaction → direct bridge to bondigoo

Examples:
- ✅ `"Dein Post zur Stressbewältigung im Führungsalltag hat mich direkt angesprochen."`
- ✅ `"Dein Ansatz, Burnout-Prävention mit Körperwahrnehmung zu verbinden, ist selten so klar erklärt."`
- ✅ `"Deine Positionierung als Career Coach speziell für Quereinsteiger fällt positiv auf."`
- ❌ `"Dein Profil sieht toll aus."` (too generic)
- ❌ `"Ich habe deine Website besucht..."` (surveillance feeling)

> [!TIP]
> **Phase 2 DM language shift:** Lead with "Wissen teilen" (knowledge sharing) instead of "Coaches suchen und buchen" (finding and booking coaches). This avoids triggering the "this commoditizes my profession" reaction from traditional coaches.

Save drafts to:
- `Coach_Data/instagram_outreach_drafts/[username]_dm.txt`
- Also update `dm_drafted = yes` in the CSV

### Step 7 — User Review

Notify the user:
- Total drafts generated
- Output folder path
- Reminder: review each draft, personalize if needed, then send manually via Instagram DM

The user sends all DMs manually from the Instagram app or web interface.

**Sending rules:**
- Max 10–15 DMs per day
- Space them out over the day (not all at once)
- Start with Founding Coaches (better signal, better feedback)

### Step 8 — Mark DMs as Sent

**Trigger:** When user says "Ich habe DMs gesendet" or "DMs sent" or "updated sent list".

User provides a list of usernames they've messaged. The agent updates the CSV:
- `dm_sent = yes`
- `dm_sent_date = [today]`

Preferred method: write a small Node.js script `Coach_Data/mark-instagram-sent.js` that:
1. Reads a comma-separated list of usernames from command line args
2. Updates the CSV for each matching username
3. Reports results

### Step 9 — Track Replies

**Trigger:** When user says "ich habe eine Antwort bekommen von [username]" or similar.

Update the CSV:
- `reply_received = yes`
- `reply_date = [today]`
- `reply_sentiment = [positive/neutral/negative]`
- `outcome = [signed_up/interested/declined/follow_up_needed]`
- `notes = [brief summary of reply]`

### Step 10 — Follow-up DM (optional)

If `outcome = follow_up_needed`, generate a short follow-up message:

```
Hey [Name], wollte kurz nachfragen ob du bondigoo schon angeschaut hast. Falls du Fragen hast, schreib einfach. Liebe Grüsse, Dominic
```

Only send after 5–7 days of no reply. Only one follow-up per contact.

---

## 📦 File Structure

```
Coach_Data/
  instagram_outreach.csv           ← master shortlist + tracking
  instagram_outreach_drafts/
    [username]_dm.txt              ← individual DM drafts
  mark-instagram-sent.js           ← script to mark DMs as sent
```

---

## 🧠 Lessons Learned

### Speed Principles (Most Important)
- **Phase 1 only** is sufficient to decide contact / no-contact. Do not add enrichment unless user asks.
- **Write raw records immediately** — a CSV row with `bio = "(to be enriched)"` is better than a perfect record still in memory.
- **All `search_web` calls in one parallel block** — never fire them sequentially.
- **Do not validate handles you already trust** — if `search_web` showed a handle, skip the OG-tag read and write directly.
- **Target speed**: ~1 qualifying record per 3 seconds in Phase 1. If slower, you are over-engineering.
- **Do not launch browser subagents during Phase 1** — they are slow, unpredictable, and not needed for discovery.

### Research
- **Hashtag pages on Instagram require login** — direct navigation to `explore/tags/` works when logged in.
- **Use `/explore/search/keyword/?q=%23[hashtag]`** instead of `/explore/tags/[hashtag]/` — more consistent loading.
- **JS batch extraction** is 10x faster than clicking through individual posts: `Array.from(document.querySelectorAll('img[alt]')).map(i=>i.alt)` returns usernames from alt text in one operation.
- **City-specific hashtags** (#coachzürich, #coachbasel) have the **highest hit rate** — nearly all results are Swiss. Broad hashtags (#coaching, #selbstentwicklung) are 80% Germany-based.
- **Similar Accounts** (from a Founding Coach's profile) yield algorithm-curated, high-relevance Swiss coaches — often better than hashtags.
- **Skip fast**: check follower count immediately on profile load. If outside 50–5000, don't read bio or posts.
- **Swiss markers to look for** in bio: city name (Zürich, Bern, Basel, Luzern, St. Gallen, Solothurn, Zug, Aarau, Winterthur), 🇨🇭 emoji, .ch link, "Schweiz", "CH".
- **Username-based de-duplication** is safe — usernames are unique on Instagram.
- **Google `site:instagram.com` searches are blocked** — do not rely on them.
- **External directories** (coaches.ch, mycoach.ch, ICF Schweiz) are inaccessible via `read_url_content` — browser subagent needed.

### Parallel Efficiency
- **3 parallel browser subagents** = 3x throughput vs single agent
- Each subagent can internally open 2–3 pages simultaneously
- Best split: Group A (cities) + Group B (niches) + Group C (mindset/broad) all in parallel
- A 4th subagent on "Similar Accounts" pays off once you have 5+ Founding Coaches in the CSV
- **Each subagent call extracts 5–10 qualifying profiles** when given a focused group of 5–6 hashtags

### DM Strategy
- **Short is better** — 3 sentences max. Instagram is casual.
- **No link in Founding Coach DM** — feels more peer-to-peer, not promotional.
- **Specific > generic** — "Dein Post zu Burnoutprävention..." gets replies; "Ich finde dein Profil toll" gets ignored.
- **Start with Founding Coaches** — their positive replies give social proof and platform feedback simultaneously.
- **10 DMs/day max** — Instagram may restrict account if too many DMs are sent quickly from a small account.

### Tools
- ✅ `browser_subagent` — use for all Instagram navigation (3–6 in parallel)
- ✅ `read_url_content("https://www.instagram.com/[username]/")` — **works without login!** Returns OG meta with exact follower/following/post counts. Use for bulk pre-filtering before browser.
- ✅ `search_web` queries (25+ in parallel) — best for username discovery without browser
- ✅ Node.js append scripts — more reliable than PowerShell for CSV manipulation
- ✅ `execute_browser_javascript` inside subagent — for batch username extraction
- ❌ `read_url_content` on Instagram for **bio text** — bio is SPA-rendered, not in OG tags
- ❌ `read_url_content` on Google `site:instagram.com` — blocked by Google
- ❌ Instagram has no public API for this use case — browser needed for bio/last-post

---

## 📊 Success Metrics

| Metric | Goal |
|---|---|
| Coaches researched | 100+ |
| DMs sent (founding tier) | 10–15 |
| DMs sent (standard tier) | 30–50 |
| Reply rate target | 15–25% |
| Sign-ups from Instagram | 5–10 before launch |
| Founding coach sign-ups | 2–3 |

## 🔢 Current Status (01.03.2026)

| Metric | Value |
|---|---|
| Total records in CSV | 120 |
| Founding coach candidates | ~25 |
| Standard coaches | ~75 |
| Dropped (too many followers / wrong country / not a coach) | ~20 |
| DMs sent | 0 |
| Founding coaches confirmed signed up | 0 |

### Phase 2 Search Queries (for FAST PATH)

Add these to the existing search_web batches:
```
# Creator-coaches (highest priority):
"online kurs coach schweiz instagram"
"workshop leiter schweiz instagram"
"mentor schweiz instagram profil"
"coaching podcast schweiz instagram"
"coaching youtube schweiz"

# Non-traditional / adjacent niches:
"stimmcoach schweiz instagram"
"finanzcoach schweiz instagram"
"dating coach schweiz instagram"
"hundetrainer schweiz instagram"
"lerncoach schweiz instagram"
"personal trainer schweiz instagram coach"
"yogalehrerin schweiz instagram"
"atemcoach schweiz instagram"

# YouTube / Podcast discovery:
"coaching podcast schweiz"
"coach youtube schweiz kanal"
"coaching podcast deutsch schweizer"
"coach interview podcast schweiz"

# Broader knowledge economy:
"trainer schweiz instagram"
"berater schweiz instagram coaching"
"experte schweiz instagram beratung"
"kursleiter schweiz instagram"
```
