heyreach-cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/AGENTS.md +385 -0
  2. package/README.md +574 -0
  3. package/package.json +4 -2
package/AGENTS.md ADDED
@@ -0,0 +1,385 @@
1
+ # AI Agent Guide — HeyReach CLI
2
+
3
+ > This file helps AI agents (GPT, Claude, Gemini, open-source models, etc.) install, authenticate, and use the HeyReach CLI to manage LinkedIn automation campaigns, leads, lists, conversations, and more via the HeyReach platform.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Install globally
9
+ npm install -g heyreach-cli
10
+
11
+ # Authenticate (non-interactive — best for agents)
12
+ export HEYREACH_API_KEY="your-api-key-here"
13
+
14
+ # Verify it works
15
+ heyreach status
16
+ ```
17
+
18
+ **Requirements:** Node.js 18+
19
+
20
+ ## Authentication
21
+
22
+ Set your API key via environment variable — no interactive login needed:
23
+
24
+ ```bash
25
+ export HEYREACH_API_KEY="your-api-key-here"
26
+ ```
27
+
28
+ Or pass it per-command:
29
+
30
+ ```bash
31
+ heyreach campaigns list --api-key "your-api-key-here"
32
+ ```
33
+
34
+ API keys are generated from: HeyReach → Settings → Integrations → Public API
35
+
36
+ ### Organization API (admin commands)
37
+
38
+ Organization commands (`heyreach org ...`) require a separate Organization API key:
39
+
40
+ ```bash
41
+ export HEYREACH_ORG_API_KEY="your-org-api-key-here"
42
+ ```
43
+
44
+ Or per-command: `heyreach org workspaces --org-key "your-org-key"`
45
+
46
+ ### Key facts
47
+
48
+ - Auth header is `X-API-KEY` (not Bearer token)
49
+ - API keys never expire but can be deleted/deactivated
50
+ - Workspace key and Organization key are separate — each has its own 300 req/min rate limit
51
+ - Base URL is fixed: `https://api.heyreach.io/api/public/`
52
+
53
+ ## Output Format
54
+
55
+ All commands output **JSON to stdout** by default — ready for parsing:
56
+
57
+ ```bash
58
+ # Default: compact JSON
59
+ heyreach campaigns list
60
+ # → {"totalCount":5,"items":[{"id":123,"name":"Q1 Outreach","status":"IN_PROGRESS",...}]}
61
+
62
+ # Pretty-printed JSON
63
+ heyreach campaigns list --pretty
64
+
65
+ # Select specific fields
66
+ heyreach campaigns list --fields id,name,status
67
+
68
+ # Suppress output (exit code only)
69
+ heyreach campaigns list --quiet
70
+ ```
71
+
72
+ **Exit codes:** 0 = success, 1 = error. Errors go to stderr as JSON:
73
+ ```json
74
+ {"error":"No API key found. Run \"heyreach login\" or set HEYREACH_API_KEY.","code":"AUTH_ERROR"}
75
+ ```
76
+
77
+ ## Discovering Commands
78
+
79
+ ```bash
80
+ # List all command groups
81
+ heyreach --help
82
+
83
+ # List subcommands in a group
84
+ heyreach campaigns --help
85
+
86
+ # Get help for a specific subcommand (shows options + examples)
87
+ heyreach campaigns list --help
88
+ ```
89
+
90
+ ## All Command Groups
91
+
92
+ ### campaigns (8 commands)
93
+ Manage LinkedIn outreach campaigns — list, get, pause, resume, add leads, stop leads, pull lead analytics.
94
+
95
+ ```
96
+ list List campaigns (paginated, filterable by keyword/status/account)
97
+ get Get a campaign by ID
98
+ resume Resume a paused campaign
99
+ pause Pause a running campaign
100
+ add-leads Add leads to a campaign (V2 — returns added/updated/failed counts)
101
+ stop-lead Stop a lead's progression in a campaign
102
+ get-leads Get leads from a campaign with status breakdowns
103
+ get-for-lead Find which campaigns a lead is enrolled in
104
+ ```
105
+
106
+ ### inbox (4 commands)
107
+ Read and respond to LinkedIn conversations across all connected accounts.
108
+
109
+ ```
110
+ list List conversations (filter by account, campaign, tags, seen status, search)
111
+ get Get a conversation with all messages by account ID + conversation ID
112
+ send Send a message to a LinkedIn conversation
113
+ set-seen Mark a conversation as seen or unseen
114
+ ```
115
+
116
+ ### accounts (2 commands)
117
+ Manage connected LinkedIn accounts.
118
+
119
+ ```
120
+ list List all LinkedIn accounts (paginated, searchable)
121
+ get Get a LinkedIn account by ID
122
+ ```
123
+
124
+ ### lists (9 commands)
125
+ Manage lead and company lists.
126
+
127
+ ```
128
+ list List all lists (filter by type, keyword, campaign)
129
+ get Get a list by ID
130
+ create Create an empty lead or company list
131
+ get-leads Get leads from a list (up to 1000 per request)
132
+ add-leads Add leads to a list (V2 — returns detailed counts)
133
+ delete-leads Delete leads from a list by LinkedIn member IDs
134
+ delete-leads-by-url Delete leads from a list by LinkedIn profile URLs
135
+ get-companies Get companies from a company list
136
+ get-for-lead Find which lists a lead belongs to
137
+ ```
138
+
139
+ ### stats (1 command)
140
+ Pull campaign analytics with day-by-day breakdown.
141
+
142
+ ```
143
+ overview Overall stats for date range (profile views, messages, connections, reply rates)
144
+ ```
145
+
146
+ ### leads (4 commands)
147
+ Look up and tag individual leads.
148
+
149
+ ```
150
+ get Get lead details by LinkedIn profile URL
151
+ add-tags Add tags to a lead (existing tags unchanged)
152
+ get-tags Get tags for a lead (alphabetically sorted)
153
+ replace-tags Remove all existing tags and replace with new tags
154
+ ```
155
+
156
+ ### lead-tags (1 command)
157
+ Create workspace-level tags.
158
+
159
+ ```
160
+ create Create one or multiple tags with display name and color
161
+ ```
162
+
163
+ ### webhooks (5 commands)
164
+ Subscribe to real-time LinkedIn events.
165
+
166
+ ```
167
+ create Create a webhook for a specific event type
168
+ get Get a webhook by ID
169
+ list List all webhooks (paginated)
170
+ update Update webhook configuration (name, URL, event type, active status)
171
+ delete Delete a webhook
172
+ ```
173
+
174
+ ### network (2 commands)
175
+ Query LinkedIn network connections.
176
+
177
+ ```
178
+ list Get network connections for a LinkedIn sender (uses pageNumber/pageSize pagination)
179
+ check Check if a lead is connected to a specific sender
180
+ ```
181
+
182
+ ### org (11 commands)
183
+ Organization management — requires Organization API key.
184
+
185
+ ```
186
+ workspaces List all workspaces
187
+ create-workspace Create a new workspace
188
+ update-workspace Update workspace name or seat limit
189
+ api-keys Get API/integration keys for a workspace
190
+ create-api-key Generate a new API key (PUBLIC, N8N, MAKE, ZAPIER, MCP)
191
+ users List all org users (filter by role, invitation status)
192
+ get-user Get user details by ID
193
+ workspace-users List users in a specific workspace
194
+ invite-admins Invite users as organization admins
195
+ invite-members Invite users with specific workspace permissions
196
+ invite-managers Invite external managers with workspace access
197
+ ```
198
+
199
+ ## Common Workflows
200
+
201
+ ### Find and tag a lead
202
+
203
+ ```bash
204
+ # Look up lead details
205
+ heyreach leads get --profile-url "https://linkedin.com/in/janedoe" --pretty
206
+
207
+ # Add tags
208
+ heyreach leads add-tags --profile-url "https://linkedin.com/in/janedoe" \
209
+ --tags "hot,enterprise" --create-if-missing
210
+
211
+ # Check which campaigns they're in
212
+ heyreach campaigns get-for-lead --profile-url "https://linkedin.com/in/janedoe" --pretty
213
+ ```
214
+
215
+ ### Add leads to a campaign
216
+
217
+ ```bash
218
+ # Add leads with full profile data
219
+ heyreach campaigns add-leads --campaign-id 123 --leads-json '[
220
+ {
221
+ "lead": {
222
+ "firstName": "Jane",
223
+ "lastName": "Doe",
224
+ "profileUrl": "https://linkedin.com/in/janedoe",
225
+ "companyName": "Acme Inc",
226
+ "position": "VP Sales",
227
+ "emailAddress": "jane@acme.com"
228
+ }
229
+ }
230
+ ]'
231
+ # → {"addedLeadsCount":1,"updatedLeadsCount":0,"failedLeadsCount":0}
232
+ ```
233
+
234
+ ### Monitor inbox for new replies
235
+
236
+ ```bash
237
+ # Check for unseen conversations
238
+ heyreach inbox list --seen false --pretty
239
+
240
+ # Read a conversation
241
+ heyreach inbox get --account-id 456 --conversation-id "conv-abc" --pretty
242
+
243
+ # Reply
244
+ heyreach inbox send --conversation-id "conv-abc" --account-id 456 \
245
+ --message "Thanks for connecting! Would love to schedule a quick call."
246
+
247
+ # Mark as seen
248
+ heyreach inbox set-seen --conversation-id "conv-abc" --account-id 456 --seen true
249
+ ```
250
+
251
+ ### Set up event notifications
252
+
253
+ ```bash
254
+ # Create a webhook for new message replies
255
+ heyreach webhooks create --name "Reply Hook" \
256
+ --url "https://your-endpoint.com/hook" \
257
+ --event-type MESSAGE_REPLY_RECEIVED
258
+
259
+ # Create a webhook for connection accepts (specific campaigns only)
260
+ heyreach webhooks create --name "Connections" \
261
+ --url "https://your-endpoint.com/hook" \
262
+ --event-type CONNECTION_REQUEST_ACCEPTED \
263
+ --campaign-ids "123,456"
264
+ ```
265
+
266
+ ### Pull analytics
267
+
268
+ ```bash
269
+ # Last 30 days overall stats
270
+ heyreach stats overview \
271
+ --start-date "2025-01-01T00:00:00Z" \
272
+ --end-date "2025-01-31T23:59:59Z" \
273
+ --pretty
274
+ # → { byDayStats: {...}, overallStats: { messagesSent, totalMessageReplies, ... } }
275
+ ```
276
+
277
+ ### Manage lists
278
+
279
+ ```bash
280
+ # Create a list
281
+ heyreach lists create --name "Q2 Targets"
282
+
283
+ # Add leads
284
+ heyreach lists add-leads --list-id 789 --leads-json '[
285
+ {"firstName":"Alex","lastName":"Chen","profileUrl":"https://linkedin.com/in/alexchen"}
286
+ ]'
287
+
288
+ # Search leads in a list
289
+ heyreach lists get-leads --list-id 789 --keyword "alex" --pretty
290
+
291
+ # Remove leads by profile URL
292
+ heyreach lists delete-leads-by-url --list-id 789 \
293
+ --urls "https://linkedin.com/in/alexchen"
294
+ ```
295
+
296
+ ### Organization admin
297
+
298
+ ```bash
299
+ # List workspaces (requires org key)
300
+ heyreach org workspaces --pretty
301
+
302
+ # Create a workspace with seat limit
303
+ heyreach org create-workspace --name "Sales Team" --seats-limit 10
304
+
305
+ # Invite a member with permissions
306
+ heyreach org invite-members \
307
+ --inviter-email "admin@company.com" \
308
+ --emails "user@company.com" \
309
+ --workspace-ids "123" \
310
+ --permissions-json '{"viewCampaigns":true,"editManageCampaigns":true,"viewLeadLists":true}'
311
+ ```
312
+
313
+ ## Pagination
314
+
315
+ Most list endpoints use offset/limit in the POST body:
316
+
317
+ ```bash
318
+ # First page (defaults: offset=0, limit=100)
319
+ heyreach campaigns list
320
+
321
+ # Next page
322
+ heyreach campaigns list --offset 100 --limit 100
323
+ ```
324
+
325
+ Response: `{ "totalCount": 250, "items": [...] }`
326
+
327
+ **Max items per request:** 100 (1000 for lead/company list queries)
328
+
329
+ **Exception:** Network commands use `--page` and `--page-size` instead of offset/limit.
330
+
331
+ ## Key Enums
332
+
333
+ **Campaign statuses:** DRAFT, IN_PROGRESS, PAUSED, FINISHED, CANCELED, FAILED, STARTING, SCHEDULED
334
+
335
+ **Webhook event types:** CONNECTION_REQUEST_SENT, CONNECTION_REQUEST_ACCEPTED, MESSAGE_SENT, MESSAGE_REPLY_RECEIVED, INMAIL_SENT, INMAIL_REPLY_RECEIVED, EVERY_MESSAGE_REPLY_RECEIVED, FOLLOW_SENT, LIKED_POST, VIEWED_PROFILE, CAMPAIGN_COMPLETED, LEAD_TAG_UPDATED
336
+
337
+ **List types:** USER_LIST, COMPANY_LIST
338
+
339
+ **Tag colors:** Blue, Green, Purple, Pink, Red, Cyan, Yellow, Orange
340
+
341
+ **API key types:** PUBLIC, N8N, MAKE, ZAPIER, MCP
342
+
343
+ **User roles:** Admin, Member, Manager
344
+
345
+ **Invitation statuses:** Unknown, Pending, Accepted, Expired, Revoked
346
+
347
+ ## MCP Server (for Claude, Cursor, VS Code)
348
+
349
+ The CLI includes a built-in MCP server exposing all 47 commands as tools:
350
+
351
+ ```bash
352
+ heyreach mcp
353
+ ```
354
+
355
+ MCP config for your AI assistant:
356
+ ```json
357
+ {
358
+ "mcpServers": {
359
+ "heyreach": {
360
+ "command": "npx",
361
+ "args": ["heyreach-cli", "mcp"],
362
+ "env": {
363
+ "HEYREACH_API_KEY": "your-key"
364
+ }
365
+ }
366
+ }
367
+ }
368
+ ```
369
+
370
+ ## Tips for AI Agents
371
+
372
+ 1. **Always use `--help`** on a group before guessing subcommand names
373
+ 2. **Parse JSON output** directly — it's the default format
374
+ 3. **Check exit codes** — 0 means success, 1 means error
375
+ 4. **Required options** are enforced with clear error messages before API calls
376
+ 5. **Rate limits** are handled automatically (300 req/min) with exponential backoff retry
377
+ 6. **Use `--fields`** to reduce output size when you only need specific data
378
+ 7. **Use `--quiet`** when you only care about success/failure
379
+ 8. **Use `--pretty`** for human-readable JSON output
380
+ 9. **Most list endpoints use POST** — the CLI handles this internally, just use the commands
381
+ 10. **Comma-separated inputs** work for arrays: `--statuses "IN_PROGRESS,PAUSED"`, `--tags "hot,priority"`
382
+ 11. **JSON inputs** use `--xxx-json` flags: `--leads-json`, `--tags-json`, `--permissions-json`
383
+ 12. **Org commands need a separate key** — set `HEYREACH_ORG_API_KEY` for `heyreach org ...` commands
384
+ 13. **Lead lookup is by profile URL** — use `--profile-url` to identify leads across most endpoints
385
+ 14. **V2 endpoints are used by default** — `add-leads` returns `{addedLeadsCount, updatedLeadsCount, failedLeadsCount}` instead of just a number
package/README.md ADDED
@@ -0,0 +1,574 @@
1
+ # HeyReach CLI
2
+
3
+ **HeyReach in your terminal.** Run LinkedIn automation campaigns, manage leads, lists, conversations, webhooks, and organization settings — from a single command line.
4
+
5
+ 47 commands across 10 API groups. Full coverage of the [HeyReach](https://heyreach.io) Public API. Built for humans, scripts, CI/CD pipelines, and AI agents.
6
+
7
+ ```bash
8
+ npm install -g heyreach-cli
9
+ ```
10
+
11
+ ---
12
+
13
+ ## What is HeyReach?
14
+
15
+ [HeyReach](https://heyreach.io) is a LinkedIn automation platform for outbound sales and lead generation. It manages:
16
+
17
+ - **LinkedIn campaigns** — multi-step outreach sequences with connection requests, messages, InMails, profile views, and post likes
18
+ - **Lead management** — import, tag, and track prospects across campaigns and lists
19
+ - **Multi-account sending** — rotate across multiple LinkedIn accounts within a single campaign
20
+ - **Unified inbox** — read and reply to LinkedIn conversations across all connected accounts
21
+ - **Webhooks** — real-time event notifications for connection accepts, replies, campaign completions, and more
22
+ - **Organization management** — workspaces, users, permissions, and API key management at the org level
23
+
24
+ ## What This CLI Enables
25
+
26
+ Every action you can take in the HeyReach dashboard, you can do from your terminal:
27
+
28
+ **Campaign operations** — list, get, pause, resume campaigns. Add leads to campaigns, stop leads mid-sequence, pull lead analytics with status breakdowns.
29
+
30
+ **Lead lifecycle** — look up any lead by LinkedIn profile URL, manage tags (add, replace, get), and track which campaigns and lists a lead belongs to.
31
+
32
+ **List management** — create lead and company lists, add/remove leads by ID or profile URL, query companies, and search leads within lists with date filters.
33
+
34
+ **Inbox management** — browse conversations with filters (account, campaign, tags, seen status), read full chatroom threads, send messages, and mark conversations as seen/unseen.
35
+
36
+ **Webhooks** — create, update, and delete webhooks for 12 event types including connection requests, message replies, InMail replies, campaign completions, and tag updates.
37
+
38
+ **Network intelligence** — query a sender's LinkedIn network and check connection status with any lead.
39
+
40
+ **Organization admin** — manage workspaces, users, API keys, and invite admins/members/managers — all via the Management API.
41
+
42
+ **AI agent integration** — every command works as both a CLI subcommand and an MCP tool, so AI assistants (Claude, Cursor, Windsurf) can manage your LinkedIn outbound directly.
43
+
44
+ ---
45
+
46
+ ## Install
47
+
48
+ ### npm (recommended)
49
+
50
+ ```bash
51
+ npm install -g heyreach-cli
52
+ ```
53
+
54
+ ### npx (zero-install)
55
+
56
+ ```bash
57
+ npx heyreach-cli campaigns list
58
+ ```
59
+
60
+ ### From source
61
+
62
+ ```bash
63
+ git clone https://github.com/bcharleson/heyreach-cli.git
64
+ cd heyreach-cli
65
+ npm install && npm run build
66
+ npm link
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Authentication
72
+
73
+ Three ways to authenticate, checked in this order:
74
+
75
+ 1. **`--api-key` flag** — pass on any command: `heyreach campaigns list --api-key <key>`
76
+ 2. **Environment variable** — `export HEYREACH_API_KEY=your-key`
77
+ 3. **Stored config** — run `heyreach login` to save your key to `~/.heyreach/config.json`
78
+
79
+ Get your API key from your HeyReach workspace settings (Settings → Integrations → Public API).
80
+
81
+ ### For AI agents and scripts
82
+
83
+ Set the environment variable — no interactive prompts, no config files:
84
+
85
+ ```bash
86
+ export HEYREACH_API_KEY=your-key
87
+ heyreach campaigns list
88
+ ```
89
+
90
+ ### Interactive login
91
+
92
+ ```bash
93
+ heyreach login
94
+ # Prompts for your API key, validates it, saves to ~/.heyreach/config.json
95
+ ```
96
+
97
+ ### Organization API (admin operations)
98
+
99
+ Organization commands (`heyreach org ...`) require a separate Organization API key:
100
+
101
+ ```bash
102
+ export HEYREACH_ORG_API_KEY=your-org-key
103
+ heyreach org workspaces --pretty
104
+ ```
105
+
106
+ Or: `heyreach login --org` to save the org key, or `--org-key <key>` per-command.
107
+
108
+ ---
109
+
110
+ ## Quick Start
111
+
112
+ ```bash
113
+ # Authenticate
114
+ heyreach login
115
+
116
+ # List your campaigns
117
+ heyreach campaigns list --pretty
118
+
119
+ # Get a specific campaign
120
+ heyreach campaigns get --campaign-id 12345 --pretty
121
+
122
+ # List LinkedIn accounts
123
+ heyreach accounts list --pretty
124
+
125
+ # Check lead details
126
+ heyreach leads get --profile-url "https://linkedin.com/in/janedoe" --pretty
127
+
128
+ # Browse inbox
129
+ heyreach inbox list --pretty
130
+
131
+ # Check API key validity
132
+ heyreach status
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Output Formats
138
+
139
+ Every command outputs JSON by default — ready for piping to `jq`, parsing in scripts, or feeding to other tools.
140
+
141
+ ```bash
142
+ # Default: compact JSON
143
+ heyreach campaigns list
144
+
145
+ # Pretty-printed JSON
146
+ heyreach campaigns list --pretty
147
+
148
+ # Select specific fields
149
+ heyreach campaigns list --fields "id,name,status"
150
+
151
+ # Suppress output (exit code only)
152
+ heyreach campaigns list --quiet
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Commands
158
+
159
+ ### Campaigns (8)
160
+
161
+ Manage LinkedIn outreach campaigns.
162
+
163
+ ```bash
164
+ heyreach campaigns list [--keyword <text>] [--statuses <list>] [--account-ids <list>]
165
+ heyreach campaigns get --campaign-id <id>
166
+ heyreach campaigns resume --campaign-id <id>
167
+ heyreach campaigns pause --campaign-id <id>
168
+ heyreach campaigns add-leads --campaign-id <id> --leads-json '<json>'
169
+ heyreach campaigns stop-lead --campaign-id <id> [--lead-url <url>] [--lead-member-id <id>]
170
+ heyreach campaigns get-leads --campaign-id <id> [--time-from <iso>] [--time-to <iso>] [--time-filter <type>]
171
+ heyreach campaigns get-for-lead [--email <e>] [--linkedin-id <id>] [--profile-url <url>]
172
+ ```
173
+
174
+ **Statuses:** DRAFT, IN_PROGRESS, PAUSED, FINISHED, CANCELED, FAILED, STARTING, SCHEDULED
175
+
176
+ **Add leads example:**
177
+ ```bash
178
+ heyreach campaigns add-leads --campaign-id 123 --leads-json '[
179
+ {
180
+ "lead": {
181
+ "firstName": "Jane",
182
+ "lastName": "Doe",
183
+ "profileUrl": "https://linkedin.com/in/janedoe",
184
+ "companyName": "Acme Inc",
185
+ "position": "VP Sales"
186
+ },
187
+ "linkedInAccountId": 456
188
+ }
189
+ ]'
190
+ ```
191
+
192
+ ### Inbox (4)
193
+
194
+ Read and respond to LinkedIn conversations.
195
+
196
+ ```bash
197
+ heyreach inbox list [--account-ids <list>] [--campaign-ids <list>] [--search <text>] [--tags <list>] [--seen <bool>]
198
+ heyreach inbox get --account-id <id> --conversation-id <id>
199
+ heyreach inbox send --conversation-id <id> --account-id <id> --message <text> [--subject <text>]
200
+ heyreach inbox set-seen --conversation-id <id> --account-id <id> --seen <bool>
201
+ ```
202
+
203
+ ### LinkedIn Accounts (2)
204
+
205
+ Manage connected LinkedIn accounts.
206
+
207
+ ```bash
208
+ heyreach accounts list [--keyword <text>]
209
+ heyreach accounts get --account-id <id>
210
+ ```
211
+
212
+ ### Lists (9)
213
+
214
+ Manage lead and company lists.
215
+
216
+ ```bash
217
+ heyreach lists list [--keyword <text>] [--list-type <type>] [--campaign-ids <list>]
218
+ heyreach lists get --list-id <id>
219
+ heyreach lists create --name <name> [--type <USER_LIST|COMPANY_LIST>]
220
+ heyreach lists get-leads --list-id <id> [--keyword <text>] [--profile-url <url>]
221
+ heyreach lists add-leads --list-id <id> --leads-json '<json>'
222
+ heyreach lists delete-leads --list-id <id> --member-ids <list>
223
+ heyreach lists delete-leads-by-url --list-id <id> --urls <list>
224
+ heyreach lists get-companies --list-id <id> [--keyword <text>]
225
+ heyreach lists get-for-lead [--email <e>] [--linkedin-id <id>] [--profile-url <url>]
226
+ ```
227
+
228
+ **List types:** USER_LIST (default), COMPANY_LIST
229
+
230
+ ### Stats (1)
231
+
232
+ Pull campaign analytics.
233
+
234
+ ```bash
235
+ heyreach stats overview --start-date <iso> --end-date <iso> [--account-ids <list>] [--campaign-ids <list>]
236
+ ```
237
+
238
+ Returns day-by-day and overall stats: profile views, messages sent/replied, connections sent/accepted, InMails, reply rates, and acceptance rates.
239
+
240
+ ### Leads (4)
241
+
242
+ Look up and tag individual leads.
243
+
244
+ ```bash
245
+ heyreach leads get --profile-url <url>
246
+ heyreach leads add-tags --tags <list> [--profile-url <url>] [--linkedin-id <id>] [--create-if-missing]
247
+ heyreach leads get-tags --profile-url <url>
248
+ heyreach leads replace-tags --tags <list> [--profile-url <url>] [--linkedin-id <id>] [--create-if-missing]
249
+ ```
250
+
251
+ ### Lead Tags (1)
252
+
253
+ Create workspace-level tags.
254
+
255
+ ```bash
256
+ heyreach lead-tags create --tags-json '[{"displayName":"Hot","color":"Red"},{"displayName":"Priority","color":"Blue"}]'
257
+ ```
258
+
259
+ **Tag colors:** Blue, Green, Purple, Pink, Red, Cyan, Yellow, Orange
260
+
261
+ ### Webhooks (5)
262
+
263
+ Subscribe to real-time LinkedIn events.
264
+
265
+ ```bash
266
+ heyreach webhooks list
267
+ heyreach webhooks get --webhook-id <id>
268
+ heyreach webhooks create --name <name> --url <url> --event-type <type> [--campaign-ids <list>]
269
+ heyreach webhooks update --webhook-id <id> [--name <n>] [--url <u>] [--event-type <t>] [--active <bool>]
270
+ heyreach webhooks delete --webhook-id <id>
271
+ ```
272
+
273
+ **Event types:** CONNECTION_REQUEST_SENT, CONNECTION_REQUEST_ACCEPTED, MESSAGE_SENT, MESSAGE_REPLY_RECEIVED, INMAIL_SENT, INMAIL_REPLY_RECEIVED, EVERY_MESSAGE_REPLY_RECEIVED, FOLLOW_SENT, LIKED_POST, VIEWED_PROFILE, CAMPAIGN_COMPLETED, LEAD_TAG_UPDATED
274
+
275
+ ### Network (2)
276
+
277
+ Query LinkedIn network connections.
278
+
279
+ ```bash
280
+ heyreach network list --sender-id <id> [--page <n>] [--page-size <n>]
281
+ heyreach network check --sender-account-id <id> [--lead-profile-url <url>] [--lead-linkedin-id <id>]
282
+ ```
283
+
284
+ ### Organization Management (11)
285
+
286
+ Manage workspaces, users, and API keys. **Requires Organization API key** (`--org-key` or `HEYREACH_ORG_API_KEY`).
287
+
288
+ ```bash
289
+ heyreach org workspaces [--offset <n>] [--limit <n>]
290
+ heyreach org create-workspace --name <name> [--seats-limit <n>]
291
+ heyreach org update-workspace --workspace-id <id> [--name <n>] [--seats-limit <n>]
292
+ heyreach org api-keys --workspace-id <id>
293
+ heyreach org create-api-key --workspace-id <id> --type <PUBLIC|N8N|MAKE|ZAPIER|MCP>
294
+ heyreach org users [--role <Admin|Member|Manager>] [--invitation-status <list>]
295
+ heyreach org get-user --user-id <id>
296
+ heyreach org workspace-users --workspace-id <id> [--role <role>]
297
+ heyreach org invite-admins --inviter-email <email> --emails <list>
298
+ heyreach org invite-members --inviter-email <email> --emails <list> --workspace-ids <list> --permissions-json '<json>'
299
+ heyreach org invite-managers --inviter-email <email> --emails <list> --workspace-ids <list>
300
+ ```
301
+
302
+ ---
303
+
304
+ ## Pagination
305
+
306
+ Most list endpoints use offset/limit pagination in the POST body:
307
+
308
+ ```bash
309
+ # First page (default: offset=0, limit=100)
310
+ heyreach campaigns list
311
+
312
+ # Second page
313
+ heyreach campaigns list --offset 100 --limit 100
314
+
315
+ # Smaller pages
316
+ heyreach campaigns list --offset 0 --limit 25
317
+ ```
318
+
319
+ Response format: `{ "totalCount": 250, "items": [...] }`
320
+
321
+ **Exception:** Network commands use `--page` and `--page-size` instead of offset/limit.
322
+
323
+ ---
324
+
325
+ ## Common Workflows
326
+
327
+ ### Launch a LinkedIn campaign with leads
328
+
329
+ ```bash
330
+ # 1. Create a lead list
331
+ LIST=$(heyreach lists create --name "Q2 Prospects" | jq -r '.id')
332
+
333
+ # 2. Add leads to the list
334
+ heyreach lists add-leads --list-id "$LIST" --leads-json '[
335
+ {"firstName":"Alex","lastName":"Chen","profileUrl":"https://linkedin.com/in/alexchen","companyName":"TechCo","position":"CTO"},
336
+ {"firstName":"Sarah","lastName":"Kim","profileUrl":"https://linkedin.com/in/sarahkim","companyName":"StartupXYZ","position":"VP Sales"}
337
+ ]'
338
+
339
+ # 3. Add leads to a campaign (assumes campaign already exists)
340
+ heyreach campaigns add-leads --campaign-id 12345 --leads-json '[
341
+ {"lead":{"profileUrl":"https://linkedin.com/in/alexchen"}},
342
+ {"lead":{"profileUrl":"https://linkedin.com/in/sarahkim"}}
343
+ ]'
344
+
345
+ # 4. Resume the campaign
346
+ heyreach campaigns resume --campaign-id 12345
347
+ ```
348
+
349
+ ### Monitor replies and conversations
350
+
351
+ ```bash
352
+ # Check for new conversations
353
+ heyreach inbox list --seen false --pretty
354
+
355
+ # Read a specific conversation
356
+ heyreach inbox get --account-id 456 --conversation-id "conv-abc" --pretty
357
+
358
+ # Reply to a conversation
359
+ heyreach inbox send --conversation-id "conv-abc" --account-id 456 --message "Thanks for connecting!"
360
+
361
+ # Mark as seen
362
+ heyreach inbox set-seen --conversation-id "conv-abc" --account-id 456 --seen true
363
+ ```
364
+
365
+ ### Tag and track leads
366
+
367
+ ```bash
368
+ # Look up a lead
369
+ heyreach leads get --profile-url "https://linkedin.com/in/janedoe" --pretty
370
+
371
+ # Add tags
372
+ heyreach leads add-tags --profile-url "https://linkedin.com/in/janedoe" --tags "hot,enterprise" --create-if-missing
373
+
374
+ # See which campaigns they're in
375
+ heyreach campaigns get-for-lead --profile-url "https://linkedin.com/in/janedoe" --pretty
376
+
377
+ # See which lists they're on
378
+ heyreach lists get-for-lead --profile-url "https://linkedin.com/in/janedoe" --pretty
379
+ ```
380
+
381
+ ### Set up webhooks for real-time events
382
+
383
+ ```bash
384
+ # Create a webhook for new replies
385
+ heyreach webhooks create --name "Reply Notifications" \
386
+ --url "https://your-endpoint.com/heyreach-hook" \
387
+ --event-type MESSAGE_REPLY_RECEIVED
388
+
389
+ # Create a webhook for connection accepts
390
+ heyreach webhooks create --name "Connection Accepts" \
391
+ --url "https://your-endpoint.com/heyreach-hook" \
392
+ --event-type CONNECTION_REQUEST_ACCEPTED \
393
+ --campaign-ids "123,456"
394
+
395
+ # List all webhooks
396
+ heyreach webhooks list --pretty
397
+ ```
398
+
399
+ ### Pull campaign analytics
400
+
401
+ ```bash
402
+ # Overall stats for last 30 days
403
+ heyreach stats overview \
404
+ --start-date "2025-01-01T00:00:00Z" \
405
+ --end-date "2025-01-31T23:59:59Z" \
406
+ --pretty
407
+
408
+ # Stats for specific campaigns
409
+ heyreach stats overview \
410
+ --start-date "2025-01-01T00:00:00Z" \
411
+ --end-date "2025-01-31T23:59:59Z" \
412
+ --campaign-ids "123,456" \
413
+ --pretty
414
+ ```
415
+
416
+ ### Organization administration
417
+
418
+ ```bash
419
+ # List workspaces (requires org key)
420
+ export HEYREACH_ORG_API_KEY=your-org-key
421
+ heyreach org workspaces --pretty
422
+
423
+ # Create a new workspace
424
+ heyreach org create-workspace --name "Sales Team" --seats-limit 10
425
+
426
+ # Invite a member with specific permissions
427
+ heyreach org invite-members \
428
+ --inviter-email "admin@company.com" \
429
+ --emails "newuser@company.com" \
430
+ --workspace-ids "123" \
431
+ --permissions-json '{"viewCampaigns":true,"viewLeadLists":true,"viewLinkedInSenderInboxes":true}'
432
+
433
+ # Generate an API key for a workspace
434
+ heyreach org create-api-key --workspace-id 123 --type PUBLIC
435
+ ```
436
+
437
+ ---
438
+
439
+ ## MCP Server
440
+
441
+ The CLI doubles as an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server, giving AI assistants direct access to all 47 HeyReach tools as native function calls.
442
+
443
+ ```bash
444
+ heyreach mcp
445
+ ```
446
+
447
+ ### What this means
448
+
449
+ When you configure `heyreach mcp` as an MCP server in Claude, Cursor, VS Code, or Windsurf, your AI assistant can:
450
+
451
+ - List and manage LinkedIn campaigns mid-conversation
452
+ - Look up leads, check tags, and browse conversations on demand
453
+ - Send LinkedIn messages and manage inbox directly
454
+ - Create webhooks and monitor campaign analytics
455
+ - Handle org-level admin tasks (workspaces, users, API keys)
456
+
457
+ Every `CommandDefinition` in the codebase powers both a CLI subcommand and an MCP tool — one source of truth, two interfaces.
458
+
459
+ ### Configuration
460
+
461
+ Add to your MCP settings (Claude Desktop, Cursor, VS Code, Windsurf):
462
+
463
+ ```json
464
+ {
465
+ "mcpServers": {
466
+ "heyreach": {
467
+ "command": "npx",
468
+ "args": ["heyreach-cli", "mcp"],
469
+ "env": {
470
+ "HEYREACH_API_KEY": "your-api-key"
471
+ }
472
+ }
473
+ }
474
+ }
475
+ ```
476
+
477
+ This registers 47 tools across 10 groups:
478
+
479
+ | Group | Tools | Examples |
480
+ |-------|-------|---------|
481
+ | Campaigns | 8 | `campaigns_list`, `campaigns_resume`, `campaigns_add_leads` |
482
+ | Inbox | 4 | `inbox_list`, `inbox_get`, `inbox_send`, `inbox_set_seen` |
483
+ | Accounts | 2 | `accounts_list`, `accounts_get` |
484
+ | Lists | 9 | `lists_list`, `lists_create`, `lists_add_leads`, `lists_get_companies` |
485
+ | Stats | 1 | `stats_overview` |
486
+ | Leads | 4 | `leads_get`, `leads_add_tags`, `leads_get_tags`, `leads_replace_tags` |
487
+ | Lead Tags | 1 | `lead_tags_create` |
488
+ | Webhooks | 5 | `webhooks_create`, `webhooks_list`, `webhooks_update`, `webhooks_delete` |
489
+ | Network | 2 | `network_list`, `network_check` |
490
+ | Org | 11 | `org_workspaces`, `org_users`, `org_invite_members`, `org_create_api_key` |
491
+
492
+ ---
493
+
494
+ ## API Reference
495
+
496
+ - **Base URL:** `https://api.heyreach.io/api/public/`
497
+ - **Auth header:** `X-API-KEY` (not Bearer token)
498
+ - **Rate limit:** 300 requests/minute (Organization API has its own separate 300 req/min limit)
499
+ - **Pagination:** POST body `{ offset, limit }` → response `{ totalCount, items[] }`
500
+ - **Max items per request:** 100 (1000 for lead/company list queries)
501
+
502
+ Full API docs: [HeyReach API Documentation](https://documenter.getpostman.com/view/23808049/2sA2xb5F75)
503
+
504
+ ---
505
+
506
+ ## Architecture
507
+
508
+ Every command is a `CommandDefinition` — one source of truth powering both the CLI subcommand and the MCP tool:
509
+
510
+ ```
511
+ src/
512
+ ├── core/
513
+ │ ├── types.ts # CommandDefinition interface
514
+ │ ├── client.ts # HTTP client (X-API-KEY, retry, rate limit, pagination)
515
+ │ ├── auth.ts # API key resolution (flag → env → config)
516
+ │ ├── config.ts # ~/.heyreach/ config management
517
+ │ ├── errors.ts # Typed error classes
518
+ │ ├── output.ts # JSON output formatting
519
+ │ └── handler.ts # Request builder from CommandDefinition
520
+ ├── commands/
521
+ │ ├── campaigns/ # 8 commands
522
+ │ ├── inbox/ # 4 commands
523
+ │ ├── accounts/ # 2 commands
524
+ │ ├── lists/ # 9 commands
525
+ │ ├── stats/ # 1 command
526
+ │ ├── leads/ # 4 commands
527
+ │ ├── lead-tags/ # 1 command
528
+ │ ├── webhooks/ # 5 commands
529
+ │ ├── network/ # 2 commands
530
+ │ └── org/ # 11 commands
531
+ ├── mcp-entry.ts # MCP server (auto-registers all commands)
532
+ └── index.ts # CLI entry point
533
+ ```
534
+
535
+ Adding a new API endpoint = creating one file. It's automatically available in both CLI and MCP.
536
+
537
+ ### HTTP Client Features
538
+
539
+ - **Auto-retry** with exponential backoff on 429 (rate limit) and 5xx errors
540
+ - **Rate limit awareness** — respects `Retry-After` headers
541
+ - **Offset/limit pagination** — handles HeyReach's POST body pagination pattern
542
+ - **30-second timeout** with configurable retries (default: 3)
543
+ - **Typed errors** — `AuthError`, `NotFoundError`, `RateLimitError`, `ValidationError`, `ServerError`
544
+
545
+ ---
546
+
547
+ ## Development
548
+
549
+ ```bash
550
+ git clone https://github.com/bcharleson/heyreach-cli.git
551
+ cd heyreach-cli
552
+ bun install
553
+
554
+ bun run dev -- campaigns list # Run in dev mode (tsx)
555
+ bun run build # Build with tsup
556
+ bun run typecheck # Type-check (tsc --noEmit)
557
+ bun test # Run tests (vitest)
558
+ ```
559
+
560
+ ### Tech Stack
561
+
562
+ - **TypeScript** (ESM, strict mode)
563
+ - **Node.js 18+**
564
+ - **Commander.js** — CLI framework
565
+ - **Zod** — schema validation (shared between CLI and MCP)
566
+ - **@modelcontextprotocol/sdk** — MCP server
567
+ - **tsup** — bundler
568
+ - **vitest** — test runner
569
+
570
+ ---
571
+
572
+ ## License
573
+
574
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyreach-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "CLI and MCP server for the HeyReach LinkedIn automation platform. Manage campaigns, leads, lists, inbox, webhooks, and more — from your terminal.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,9 @@
8
8
  },
9
9
  "files": [
10
10
  "dist",
11
- "CLAUDE.md"
11
+ "README.md",
12
+ "CLAUDE.md",
13
+ "AGENTS.md"
12
14
  ],
13
15
  "scripts": {
14
16
  "dev": "tsx src/index.ts",