Claude
Skills
Sign in
Back

apify-link-prospecting-outreach

Included with Lifetime
$97 forever

Find sites ranking for target keywords, score every prospect with Ahrefs domain authority and page-level traffic, identify the strongest pitch angle per row ("links to competitor", "mentions brand without linking", "top-3 SERP", "resource page", "outdated content"), generate brand-voice-matched outreach emails using an outreach-type-aware template (unlinked-mention claim, competitor-link replacement, resource-page inclusion, outdated-content replacement, topical niche-edit), and propose a concrete in-article link placement as three artifacts — the verbatim source sentence, the same sentence rewritten with the link spliced in, or a fully-drafted new insertion if no natural fit exists. Use when user asks to find link building opportunities, prospect link partners, recover unlinked brand mentions, replace competitor links, build a tiered outreach list, or run cold email outreach for SEO link building.

Ads & Marketingscripts

What this skill does


# Link Prospecting Outreach

Turn a goal + a target keyword + a URL the user wants to promote into a tiered, ready-to-send outreach list: SERP-ranking prospects with Ahrefs-scored authority, the strongest pitch angle per prospect, an outreach-type-matched email draft, and a copy-paste-ready link placement.

## Prerequisites
(No need to check it upfront)

- `.env` file with `APIFY_TOKEN`
- Ahrefs MCP available (the skill calls `mcp__claude_ai_Ahrefs__*` tools for prospect scoring)
- Node.js 20.6+ (for native `--env-file` support)
- One-time setup inside the skill's `scripts/` folder: `npm install`

## Helper scripts (one config, four steps)

After Step 1–2 inputs are collected, write them to a single **`campaign.json`** (schema in [`campaign.json.example`](campaign.json.example)). Every downstream script reads `--config campaign.json`, so the agent doesn't fork per-campaign copies. Sequence:

```bash
# 1. Run the Actor (writes {base}.json + sub-Actor sidecars when --fetch-sub-datasets)
node --env-file=.env scripts/run_actor.js --actor "apify/link-prospecting-tool" --input '<json>' --timeout 1800 --fetch-sub-datasets --output {base}.json --format json

# 2. Build unified prospect table from the sidecars
python3 scripts/build_prospects.py --config campaign.json

# 3. (After Step 5 Ahrefs MCP calls → save to {base}_ahrefs_domain.json + {base}_ahrefs_page.json)
python3 scripts/enrich_prospects.py --config campaign.json

# 4. (After Step 8 sub-agents write outputs to /tmp/placement_outputs/row_*.json)
python3 scripts/merge_subagent_outputs.py --config campaign.json --outputs-dir /tmp/placement_outputs

# 5. Write the final xlsx + metadata sidecar
python3 scripts/write_xlsx.py --config campaign.json
```

If the runner's client-side wait elapses with the Actor still running on Apify, use `scripts/fetch_run_artifacts.js --run-id <id> --output {base}.json` instead of restarting. If the parent run is missing `SUB_ACTOR_RESULTS` (post-2026-05-20 Actor schema), `scripts/fetch_subactors_from_log.js` resolves sub-Actor runIds from the parent log.

## Workflow

Copy this checklist and track progress:

```
Task Progress:
- [ ] Step 1: Collect required anchor inputs incl. goal (block on these)
- [ ] Step 2: Collect brand voice, partnership type, output format
- [ ] Step 3: Run apify/link-prospecting-tool
- [ ] Step 4: Pull leads, mentions, authors, and sub-Actor datasets
- [ ] Step 5: Enrich every domain with Ahrefs metrics, assign Prospect Tier
- [ ] Step 6: Run skip pass — flag rows to drop before drafting
- [ ] Step 7: Compute "Why This Prospect" tag per surviving row
- [ ] Step 8: Compose per-row 3-artifact placement + outreach-type-aware email
- [ ] Step 9: Render output in chosen format
```

### Step 1: Required Anchor Inputs (ask FIRST, before anything else)

Do NOT proceed to Step 2 until every required input is answered. Surface them as the very first interaction. The dedup input (#7) is optional but must still be explicitly asked.

1. **Concrete goal for this campaign** — pick one preset or supply custom text. The goal drives skip-pass filtering, outreach-type template selection, and Prospect Tier thresholds. Required.

   | Preset | Effect downstream |
   |---|---|
   | `Recover unlinked brand mentions` | Skip pass drops every row where `brand_mentioned_in_source` is `false`. Default outreach type = `unlinked-mention-claim`. |
   | `Replace competitor links` | Skip pass drops every row not tagged `Links to competitor`. Default outreach type = `competitor-link-replacement`. |
   | `Topical authority links to specific URL` | No filter. Tier thresholds tighten (DR ≥ 50 for tier A). Default outreach type chosen per-row from `Why This Prospect`. |
   | `Maximum link volume from any relevant site` | No filter. Tier thresholds relax (DR ≥ 30 for tier A). Default outreach type chosen per-row. |
   | `Custom` | User-supplied paragraph; biases email tone and tier weights. No automatic skip filter. |

2. **Target keyword(s)** — one or more keywords the user wants their link to appear next to. The skill prospects the SERP for each. At least one required.
3. **Brand name** — the user's brand or product name. The Actor will not run without this (it is the `brand` input field).
4. **Product/category description** — one or two sentences describing what the user sells, who they sell to, and what category their product fits in. Example: *"Apify — web scraping platform that runs serverless scrapers as APIs. We sell to developers and data teams who need scraped data without managing infrastructure."* Required. Used in Step 6 (topical-fit gate) and Step 7 (adversarial-mention detection) to recognise prospects who are in the same product category — those won't link no matter the pitch. Without this, the skill cannot distinguish a genuine editorial opportunity from a competitor's blog.
5. **URL of content to link to** — the destination URL that will be inserted into partner articles. Required.
6. **Competitors** — anyone in the user's product category who would publish a "ours vs theirs" comparison page on their own site. Frame the ask this way explicitly: *"List every company that would write an X-vs-YourBrand comparison page. These won't link to you no matter what — small competitors count too."* Encourage 10+ entries; most users default to listing 3–5 obvious ones and miss the long tail. Mapped to `competitorDomains` on the Actor and reused in Steps 6 (adversarial-mention skip) and 7 (`Links to competitor` Why-tag).

   After the user answers, **offer** (do not push) an Ahrefs auto-pull of organic competitors: *"Want me to pull your top organic competitors from Ahrefs and add them to this list? Adds ~50 API units and surfaces smaller competitors you may have missed."* If the user says yes and Ahrefs MCP is available, call `mcp__claude_ai_Ahrefs__site-explorer-organic-competitors` on the user's domain (extracted from input #5) and merge results into `competitorDomains`. If Ahrefs is unavailable or the user declines, proceed with the user-supplied list only.
7. **Already-pitched domains (optional)** — domains the user has already contacted in past campaigns. Accept a comma-separated list, a CSV/Sheet path, or "none". The skill drops these in the skip pass so the user doesn't double-pitch. Not required to proceed.
8. **Number of organic results per keyword** — how many Google organic SERP results to prospect per keyword. Default 10 if the user is unsure, but ask the question so the user knows the lever exists. Mapped to `organicResult`.
9. **LLM sources to track** — multi-select. Each enabled engine queries an additional AI search/chat surface and adds Google Search Scraper sub-Actor cost per result fetched. Default: all enabled. Mapping to Actor input flags:

   | Option | Actor flag | Cost impact |
   |---|---|---|
   | ChatGPT Search | `enableChatGpt` | Per-result Google Search Scraper cost |
   | Gemini | `enableGemini` | Per-result Google Search Scraper cost |
   | Copilot (Microsoft / Bing) | `enableCopilot` | Per-result Google Search Scraper cost |
   | Perplexity | `enablePerplexity` | Per-result Google Search Scraper cost |
   | Google AI Mode | `enableAiMode` | Per-result Google Search Scraper cost |
   | Google AI Overviews | `enableAiOverviews` | **Free** — parsed from the SERP already fetched. Keep on regardless of budget. |

   Surface the multi-select to the user with all six pre-checked. Disabling individual engines is the main cost-cutting lever short of dropping `organicResult` — recommend keeping ChatGPT + Gemini on at minimum (they capture the largest share of LLM-driven discovery traffic in 2026).
10. **Run email verification?** — boolean. Default: `yes`. Mapped to `enableEmailVerification` on the Actor. When enabled, the Actor verifies every email returned by the Contact Details Scraper sub-Actor and tags each lead with a verification status (`verified` / `catch-all` / `risky` / `invalid` / `unknown`). The skill uses the status in Step 6 (invalid emails g

Related in Ads & Marketing