Skip to content
Agentmart
Submit a tool

linkedin-growth

Two-phase LinkedIn lead pipeline driven by linkedin-cli.

Skill by Linked-API

IndexedMIT★ 104
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/linked-api-linkedin-growth

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Two-phase LinkedIn lead pipeline driven by linkedin-cli. Phase A imports leads from a search URL or filters, qualifies them against a configurable ICP via sub-agent, and stores them in a local SQLite database with round-robin assignment across one or more LinkedIn accounts. Phase B runs on a schedule per account — sends connection invites up to a daily limit and withdraws stale pending requests. Use when the user wants to grow their network from LinkedIn searches, manage outgoing invites at scale, ask status questions (counts, conversion, pending older than N days, last imports), pause/resume an account, change ICP, or install the recurring scheduler.

Use cases: backend, data, marketing, sales

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 3

  • api.notion.com · found in code
  • apple.com · found in code
  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/linkedin-growth
  • Your home directory (~)

What's inside

Skill name
linkedin-growth
Description
Two-phase LinkedIn lead pipeline driven by linkedin-cli. Phase A imports leads from a search URL or filters, qualifies them against a configurable ICP via sub-agent, and stores them in a local SQLite database with round-robin assignment across one or more LinkedIn accounts. Phase B runs on a schedule per account — sends connection invites up to a daily limit and withdraws stale pending requests. Use when the user wants to grow their network from LinkedIn searches, manage outgoing invites at scale, ask status questions (counts, conversion, pending older than N days, last imports), pause/resume an account, change ICP, or install the recurring scheduler.
License
MIT
Instructions
477 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (37)

  • .gitignore
  • README.md
  • SKILL.md
  • linkedin-growth-config.md · commands/
  • linkedin-growth-import.md · commands/
  • linkedin-growth-setup.md · commands/
  • linkedin-growth-status.md · commands/
  • defaults.json · config/
  • qualification-prompt.md · config/
  • package.json
  • account.mjs · scripts/
  • db.mjs · scripts/
  • doctor.mjs · scripts/
  • export.mjs · scripts/
  • import.mjs · scripts/
  • lead.mjs · scripts/
  • account.mjs · scripts/lib/
  • args.mjs · scripts/lib/
  • cli.mjs · scripts/lib/
  • config.mjs · scripts/lib/
  • db.mjs · scripts/lib/
  • output.mjs · scripts/lib/
  • paths.mjs · scripts/lib/
  • retry.mjs · scripts/lib/
  • runs.mjs · scripts/lib/
  • settings.mjs · scripts/lib/
  • time.mjs · scripts/lib/
  • migrate-notion.mjs · scripts/
  • network-invite.mjs · scripts/
  • network-pending.mjs · scripts/
  • network-run.mjs · scripts/
  • query.mjs · scripts/
  • schedule.mjs · scripts/
  • schema.mjs · scripts/
  • settings.mjs · scripts/
  • status.mjs · scripts/
  • tick.mjs · scripts/

SKILL.md (first lines)

# LinkedIn Growth Skill

This skill turns a Sales Navigator (or regular) search into a managed pipeline:
**search → qualify (you, via sub-agent) → store → invite on schedule → check pending → withdraw stale**.

All state lives in a local SQLite database. Every LinkedIn action goes through
`linkedin-cli` (the `linkedin` binary). You orchestrate via the Node scripts
under `scripts/`.

## Vocabulary

| Term | Meaning |
|------|---------|
| **Account** | A LinkedIn account registered in `linkedin-cli` AND added to this skill's DB. The DB stores per-account policy (`daily_invite_limit`, `active_start`/`active_end` hours, `max_pending_days`, `paused`). |
| **Lead** | A qualified person row in `leads`. PK is `hashed_url` (Sales Nav hashed URL for `nv` imports, or `publicUrl` for `st` imports). Has exactly one `owner_account`. |
| **List** | A free-text `list_name` attached at import time (e.g. "VP of Sales TOP 100"). Used for filtering and conversion analytics. |
| **Batch** | A row in `import_batches`. Created by `import.mjs prepare`; transitions `pending_qualification → committed | aborted`. |
| **Status** | A lead's lifecycle state: `not_connected → pending → (connected | exhausted | error)`. `not_connected` means ready for an invite from `owner_account` (could be the 1st attempt or a retry under a different account). `connected` = success (terminal). `exhausted` = tried up to `max_connect_attempts` accounts, none accepted (terminal). `error` = an invite failed technically (manual reset). |
| **Retry policy** | Global `max_connect_attempts` setting. When an account's attempt fails (we withdrew a stale pending, OR the person declined/expired), the lead is reassigned to another untried account and set back to `not_connected` — until `max_connect_attempts` distinct accounts have tried, then it becomes `exhausted`. `1` = no retry (default); `all` = try every active account. |
| **Phase A** | Import — runs only when the user triggers it. Includes the LLM step (you, via sub-agent). |
| **Phase B** | Network maintenance — `network-invite` + `network-pending`. Runs on a schedule. NEVER calls an LLM. |

## First-run setup

**1. Verify Node ≥ 20:** `node --version`.
If missing — print the OS-specific install command and stop:
- macOS: `brew install node`
- Linux: `apt install nodejs` / `dnf install nodejs` / etc., or nvm
- Windows: `winget install OpenJS.NodeJS.LTS`

**2. From this skill's directory, run:**

```bash
node scripts/doctor.mjs --json
```

If the output is `Cannot find module 'better-sqlite3'`:

```bash
npm install --omit=dev
```

Then re-run doctor. (Alternative: `node scripts/doctor.mjs --fix` does this automatically.)

**3. For each FAIL in the doctor output, apply the remediation:**

| Check name | Remediation |
|------------|-------------|
| `linkedin-cli` | `npm install -g @linkedapi/linkedin-cli` |
| `cli-accounts` | Ask the user for their Linked API Token and Identification Token (link: https://app.linkedapi.io), then `linkedin setup --linked-api-token=<a> --identification-token=<b>`. Repeat per LinkedIn account they want connected. |
| `db` | Auto-fixed by any script on first invocation, or explicitly: `node scripts/db.mjs init` |
| `db-accounts` | Run `linkedin account list` (prints a table; the `*` marks the active account) and register each one here: `node scripts/account.mjs add --name <short-name> --cli-account "<exact name from linkedin account list>"`. The short name is what every other command takes; the cli-account is the mapping. |
| `scheduler` | Should pass automatically. On headless Linux without systemd-user, doctor falls back to `cron`. |

**4. Re-run `node scripts/doctor.mjs --json` until `"ok": true`.**

**5. Set the connection pace — ask once, apply to all accounts.** Ask the user a single
question (not per account): "By default each account sends at most one connection request
every 15 minutes — keep 15, or change it?". Apply their answer to every account via
`--min-invite-interval <N>` (either pass it on each `account.mjs add`, or
`account.mjs update --name <acct> --min-invite-interval <N>` for all afterward). Default is
15. Let the user know they can fine-tune it per account later just by asking (e.g. "make
kiril one every 30 minutes") — it is a per-account setting, this question just sets a common
value for everyone.

**6. Set the retry policy.** Ask the user: "If someone doesn't accept the request, should
we try connecting from another account? (no / a specific number of accounts / all of them)".
Then:

```bash
node scripts/settings.mjs set max_connect_attempts 1      # no retry (default)
node scripts/settings.mjs set max_connect_attempts 2      # original + 1 more
node scripts/settings.mjs set max_connect_attempts all    # every account
```

**7. Enable the background scheduler (only after at least one account is registered):**

```bash
node scripts/schedule.mjs install
```

This installs one platform-native background task that keeps the pipeline running
on its own. When talking to the user, describe it as "the pipeline now runs in the
background and sends invites during each account's active hours" — do not expose the
scheduler's internal wake-up frequency (the tick) or other plumbing. (The invite *pace*
from step 5 — "one connect every N minutes" — is a real user-facing setting and fine to
discuss; it's the tick's 5-minute heartbeat that stays hidden.) See the **Phase B** and
**Scheduler** sections below for how it actually works.

**8. Tell the user the next step and offer to do it.** Setup alone sends nothing — the
pipeline is empty until leads are imported. End onboarding with a concrete call to action,
e.g.: "You're all set. To start, give me a LinkedIn or Sales Navigator search URL (or
search filters) and a name for the list, and I'll import and qualify your first batch of
leads." If the user provides one, proceed straight into **Phase A** below. Do not end the
setup conversation without this prompt.

## Phase A — Importing leads (interactive)

Triggered by the user via wording like:
- "import leads from this search ..."
- "add leads from this Sales Navigator URL"
- "add a list called 'X' from this search"

### Step 1 — Prepare

**Always ask the user for a limit first.** Before running `prepare`, ask "how many of the
found leads should I take?" — the user gives a number, or says "max" for the maximum. The
maximum depends on the search type (these are the Linked API / LinkedIn caps):
- Sales Navigator (`nv`): **2500**
- standard search (`st`): **1000**

`--limit` is **required**; `prepare` errors if it is missing. Pass `--limit max` (or `all`)
for the cap, or a number (clamped to the cap, with `limit_capped_to_max: true` reported).

```bash
node scripts/import.mjs prepare \
  --searcher <db-account-name> \
  --list "<list name>" \
  --limit <N|max> \         # REQUIRED — ask the user; 'max' = 2500 (nv) / 1000 (st)

From Linked-API/linkedin-skills, MIT.

Compare and alternatives

    Featured in

    Signals

    Stars
    104
    Forks
    19
    Open issues
    0
    Last commit (this folder)
    Jul 21, 2026 (3 months ago)

    From GitHub (fetched Oct 24, 2026).

    Details

    License
    MIT
    First seen
    Oct 24, 2026
    Last checked
    Oct 24, 2026

    More from Linked-API

    Cite this page

    linkedin-growth skill. Agent Mart. https://agentmart.dev/skills/linked-api-linkedin-growth (last updated 2026-10-24)