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.
- package/AGENTS.md +385 -0
- package/README.md +574 -0
- 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.
|
|
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
|
-
"
|
|
11
|
+
"README.md",
|
|
12
|
+
"CLAUDE.md",
|
|
13
|
+
"AGENTS.md"
|
|
12
14
|
],
|
|
13
15
|
"scripts": {
|
|
14
16
|
"dev": "tsx src/index.ts",
|