@saleshandy/saleshandy-cli
Official CLI for the SalesHandy Open API. Manage prospects, sequences, email accounts, tasks, and more from your terminal.
Install
npm install -g @saleshandy/saleshandy-cli
Requires Node.js 18 or later.
Quick Start
1. Get your API key
Go to SalesHandy API Keys Settings and generate an API key.
2. Authenticate
saleshandy auth login
# Prompts for your API key interactively
# Or pass it directly:
saleshandy auth login --api-key YOUR_API_KEY
3. Run commands
saleshandy prospects list
saleshandy sequences list --json
saleshandy tasks list --limit 5
Authentication
Login and profiles
The CLI stores your API key locally at ~/.config/saleshandy/config.json.
# Default profile
saleshandy auth login --api-key YOUR_API_KEY
# Named profile (for multiple accounts)
saleshandy auth login --api-key ANOTHER_KEY --profile client-a
# Use a specific profile for a command
saleshandy prospects list --profile client-a
# Switch default profile
saleshandy auth switch client-a
# See all profiles
saleshandy auth status
# Remove a profile
saleshandy auth logout
saleshandy auth logout --profile client-a
Environment variable
You can skip login entirely by setting the env var. This is useful for CI/CD:
export SALESHANDY_API_KEY=your_key
saleshandy prospects list
Per-command override
saleshandy prospects list --api-key YOUR_KEY
Precedence: --api-key flag > SALESHANDY_API_KEY env var > saved profile.
Output Formats
Every command supports three output formats:
# Table (default) — human-readable
saleshandy prospects list
# JSON — for scripts and piping
saleshandy prospects list --json
# CSV — for spreadsheets
saleshandy prospects list --csv
Pipe JSON output to jq for filtering:
saleshandy prospects list --json | jq '.[].email'
Export to a CSV file:
saleshandy prospects list --csv > contacts.csv
Disable colored output:
saleshandy prospects list --no-color
Getting Help
# List all topics
saleshandy --help
# List commands in a topic
saleshandy prospects --help
# See flags, args, and examples for a specific command
saleshandy prospects list --help
saleshandy analytics sequence-stats --help
Every command has --help. When in doubt, add --help to see exactly what flags and arguments are required.
Common Patterns
Pagination
All list commands support --limit and --page:
saleshandy prospects list --limit 50 --page 1
saleshandy prospects list --limit 50 --page 2
Sorting
List commands support --sort (asc/desc) and --sort-by:
saleshandy prospects list --sort desc --sort-by createdAt
saleshandy tasks list --sort-order ASC --sort-by priority
Note: Valid --sort-by values differ per resource. Run <command> --help to see available options.
Passing IDs
Many commands require IDs (sequence IDs, prospect IDs, etc.). IDs in SalesHandy are hashed strings like gOwE5l64wb. You get these from list commands:
# Step 1: List sequences to find the ID
saleshandy sequences list
# Output shows ID column: gOwE5l64wb
# Step 2: Use that ID in another command
saleshandy analytics sequence-stats --sequence-id gOwE5l64wb
Comma-separated IDs
Some commands accept multiple IDs. Pass them comma-separated:
saleshandy sequences status-update --sequence-ids gOwE5l64wb,aB3xK9mP2w --status pause
saleshandy tasks bulk-skip --task-ids id1,id2,id3
JSON body via --file
Import and connect commands accept a JSON file:
saleshandy prospects import --file prospects.json
saleshandy email-accounts connect --file accounts.json
saleshandy enrichment contact --file leads.json
Async operations (import, enrichment, connect)
Some operations are async. They return a request ID you can poll:
# Start an import
saleshandy prospects import --file data.json
# Output: ✓ Prospect import has started. Request ID: req_abc123
# Check status
saleshandy prospects import-status req_abc123
# For enrichment, use --wait to poll automatically:
saleshandy enrichment status req_abc123 --wait
Command Reference
auth — Authentication
saleshandy auth login # Interactive login
saleshandy auth login --api-key KEY # Non-interactive
saleshandy auth login --api-key KEY --profile staging
saleshandy auth logout # Remove current profile
saleshandy auth logout --profile staging # Remove named profile
saleshandy auth status # Show all profiles
saleshandy auth switch staging # Switch active profile
prospects — Manage Prospects
saleshandy prospects list # List all prospects
saleshandy prospects list --search "[email protected]" # Search by email/name
saleshandy prospects list --limit 50 --page 2 # Paginate
saleshandy prospects list --include-custom-fields # Include custom fields
saleshandy prospects import --file prospects.json # Import from file
saleshandy prospects import-status REQUEST_ID # Check import status
saleshandy prospects verification-status --emails "[email protected],[email protected]"
saleshandy prospects attribute --attribute-id ID --prospect-id ID
# Update prospect status in a sequence
saleshandy prospects status update \
--prospect-id ID --sequence-id ID --step-id ID --status paused
# Status options: replied, finished, paused, unsubscribed, active
# Tags
saleshandy prospects tags list
saleshandy prospects tags list --search "VIP"
saleshandy prospects tags assign --prospects '[{"prospectId":"ID","tagId":"ID"}]'
saleshandy prospects tags unassign --data '[{"prospects":["ID"]}]'
sequences — Manage Sequences
saleshandy sequences list # List all
saleshandy sequences list --search "Growth" --limit 10 # Filter
saleshandy sequences status-update --sequence-ids ID1,ID2 --status pause
# Email accounts on a sequence
saleshandy sequences email-accounts list --sequence-id ID
saleshandy sequences email-accounts add --sequence-id ID --email-account-ids ID1,ID2
saleshandy sequences email-accounts remove --sequence-id ID --email-account-ids ID1
# Import prospects into a sequence
saleshandy sequences prospects-import --file data.json
# Add existing contacts to a sequence step
saleshandy sequences contacts-add --sequence-id ID --step-id ID --contact-ids ID1,ID2
# Get step details
saleshandy sequences steps get --sequence-id ID --step-id ID
email-accounts — Email Accounts
saleshandy email-accounts list # List all
saleshandy email-accounts list --search "gmail" # Filter
saleshandy email-accounts connect --file accounts.json # Connect via SMTP/IMAP
saleshandy email-accounts connect-status REQUEST_ID # Check connection
saleshandy email-accounts reconnect --email-account-ids ID1,ID2
saleshandy email-accounts bulk-update --email-account-ids ID1,ID2 --is-paused
enrichment — Lead Finder
# Enrich contacts
saleshandy enrichment contact --linkedin-urls "https://linkedin.com/in/person"
saleshandy enrichment contact --file contacts.json --reveal-phone
saleshandy enrichment contact --file contacts.json --webhook-url https://example.com/hook
# Enrich companies
saleshandy enrichment company --domains "acme.com,startup.io"
saleshandy enrichment company --file companies.json
# Check status and get results
saleshandy enrichment status REQUEST_ID
saleshandy enrichment status REQUEST_ID --wait # Polls until complete
saleshandy enrichment result REQUEST_ID
# Check credits and rate limits
saleshandy enrichment credits
saleshandy enrichment rate-limits
unified-inbox — Emails
saleshandy unified-inbox unread-count
saleshandy unified-inbox outcomes --limit 10
saleshandy unified-inbox emails list --limit 20 --search "acme"
saleshandy unified-inbox emails list --sentiment positive --start-date 2025-01-01
saleshandy unified-inbox emails thread THREAD_ID
saleshandy unified-inbox emails get THREAD_ID EMAIL_ID
# Reply to an email
saleshandy unified-inbox emails reply \
--thread-id ID --email-id ID \
--to "[email protected]" --content "Thanks for reaching out!"
analytics — Reports
# Sequence stats (pass sequence ID from `sequences list`)
saleshandy analytics sequence-stats --sequence-id gOwE5l64wb
# Consolidated stats across multiple sequences
saleshandy analytics consolidated-stats \
--sequence-ids ID1,ID2 --start-date 2025-01-01 --end-date 2025-12-31
# Email account stats
saleshandy analytics email-account-stats --email-id ID
# Team stats
saleshandy analytics team-stats \
--user-ids ID1,ID2 \
--start-date 2025-01-01T00:00:00.000+00:00 \
--end-date 2025-12-31T23:59:59.000+00:00 \
--count-by absolute --type prospect \
--order-by total --limit 10 --page 1
tasks — Task Management
saleshandy tasks list # List all tasks
saleshandy tasks list --status overdue --limit 10 # Filter by status
saleshandy tasks list --sequence-id ID # Filter by sequence
saleshandy tasks get TASK_ID # Task details
saleshandy tasks counts # Counts by status
saleshandy tasks assignees # List assignees
# Actions
saleshandy tasks complete TASK_ID
saleshandy tasks skip TASK_ID
saleshandy tasks snooze TASK_ID --snooze-until "2025-12-25T09:00:00.000Z"
saleshandy tasks note-update TASK_ID --note "Called, no answer"
# Bulk actions
saleshandy tasks bulk-skip --task-ids ID1,ID2,ID3
saleshandy tasks bulk-snooze --task-ids ID1,ID2 --snooze-until "2025-12-25T09:00:00.000Z"
saleshandy tasks bulk-status BULK_ACTION_ID
dnc — Do Not Contact
saleshandy dnc list # List DNC lists
saleshandy dnc items DNC_LIST_ID # Items in a list
saleshandy dnc add --dnc-list-id ID --items "[email protected],baddomain.com"
saleshandy dnc search --search "bad.com" --type domain
fields — Custom Fields
saleshandy fields list --system-fields # Include system fields
saleshandy fields list --no-system-fields # Custom fields only
clients — Client Management
saleshandy clients list
saleshandy clients list --search "Acme"
saleshandy clients assign --resource-type sequence --client-id ID --resource-ids ID1,ID2
saleshandy clients assign --resource-type emailAccount --client-id ID --resource-ids ID1
user — Team Info
saleshandy user team-members
saleshandy user team-members --json
warmup — Email Warmup
saleshandy warmup report EMAIL_ACCOUNT_ID 2025-03-15
Global Flags
These flags work on every command:
| Flag | Description |
|---|---|
--json | Output as JSON |
--csv | Output as CSV |
--profile <name> | Use a named auth profile |
--api-key <key> | Override API key for this command |
--no-color | Disable colored output |
--help | Show help |
Shell Autocomplete
Set up tab completion:
saleshandy autocomplete
Follow the printed instructions for your shell (bash/zsh/fish).
FAQ
Q: How do I find the ID I need to pass to a command?
A: Run the list command for that resource first. For example, saleshandy sequences list shows sequence IDs, then use that ID with saleshandy analytics sequence-stats --sequence-id <ID>.
Q: A command says a flag is required but I don't know the value.
A: Run <command> --help to see the description and valid options for each flag. For IDs, list the parent resource first.
Q: How do I pass JSON data?
A: Use --file path/to/file.json for import/connect/enrichment commands. For tag operations, pass inline JSON as a string: --prospects '[{"prospectId":"ID","tagId":"ID"}]'
Q: Can I use this in CI/CD?
A: Yes. Set SALESHANDY_API_KEY as an environment variable and use --json for machine-readable output. Example: SALESHANDY_API_KEY=xxx saleshandy prospects list --json
Q: How do I check the status of an async operation?
A: Import, enrichment, and connect operations return a request ID. Use the corresponding *-status command: saleshandy prospects import-status <requestId> or saleshandy enrichment status <requestId> --wait