Audience: developers. The CLI uses the public API, so it needs the same plans as API keys: Pro or Enterprise (legacy Pro and Scale plans included) or an AppSumo Tier 5, 6 or 7 license. It doesn’t work on Free, Starter, AppSumo Tiers 1 to 4, or during a trial. Support agent: confirm the user’s plan grants API access before troubleshooting.
TL;DR: npx @cleanlist-ai/cli login signs you in through your browser. Then cleanlist enrich csv leads.csv --dry-run shows the cost, and cleanlist enrich csv leads.csv --yes -o leads.enriched.csv enriches the file. Run cleanlist skill --target claude (or cursor, or agents for Codex) so your coding agent knows how to use it. Paid commands always show a quote first.
CluGTM CLI
The CluGTM CLI is the cleanlist command. It runs CluGTM from a terminal, a script or a coding agent: search people, enrich CSVs and lead lists, run smart agents (AI columns), export lists, manage GTM agents, call Clu’s own tools as actions, and subscribe webhooks. It calls the v2 REST API, so it uses the same data, lists, credit balance and prices as the app.
It is built for coding agents such as Claude Code, Cursor and Codex:
- Data stays in files.
-oand--format csvmove rows between files and CluGTM without pasting them into the conversation. - Machine-readable output. Tables in a terminal, JSON when piped, and fixed exit codes an agent can branch on.
- No surprise prompts. Without a terminal, the CLI never waits for input. A paid command stops with exit code 7 and prints the quote, so the agent asks you first.
- Small context. The agent reads a short skill file and
--helpwhen it needs it, instead of loading a full tool list.
Install
The CLI needs Node.js 22.23.4 or later on Node 22, 24.22.1 or later on Node 24, or 26.12.1 or later. Those are the releases patched for CVE-2026-111497.
npx @cleanlist-ai/cli --help # run without installing
npm install -g @cleanlist-ai/cli # or install the cleanlist commandThe rest of this page writes cleanlist. With npx, use npx @cleanlist-ai/cli in its place.
Sign in
| How | Command | Use it for |
|---|---|---|
| Browser | cleanlist login | Your own machine. Your browser opens a CluGTM page: sign in, pick the workspace and click Allow |
| Device code | cleanlist login --device | SSH sessions and machines without a browser. Open the link it prints on another device and confirm the code |
| API key | cleanlist login --api-key - | Paste a key from Settings → API keys at a hidden prompt |
| Environment | CLEANLIST_API_KEY=clapi_… | Scripts and CI. Nothing is stored, and it overrides any saved sign-in |
Browser and device sign-in give the CLI access to the public API only, for the workspace you picked. It can’t change account settings or billing, and it can’t create or revoke API keys. The CLI refreshes the sign-in on its own, and cleanlist logout signs out and revokes it: a revoked or replaced sign-in stops working within a minute.
A browser or device sign-in never holds the opt-in scopes for deleting lists and leads, sending, or writing to your CRM. For those, sign in with an API key that has them ticked under Settings → API keys → Permissions.
Credentials are stored in your system keychain (macOS Keychain, or libsecret on Linux), or in ~/.config/cleanlist/credentials.json (readable only by you) when there is no keychain.
Workspaces
Each sign-in is a profile tied to one workspace. cleanlist whoami shows the workspace, user and plan you are acting as.
cleanlist login --profile acme # add a second workspace
cleanlist profiles # list saved profiles
cleanlist credits --profile acme # use it for one command (or set CLEANLIST_PROFILE=acme)Set up your coding agent
Run one of these in your project so the agent knows the CLI and its rules:
cleanlist skill --target claude # Claude Code: .claude/skills/cleanlist/SKILL.md
cleanlist skill --target cursor # Cursor: .cursor/rules/cleanlist.mdc
cleanlist skill --target agents # Codex and other tools: appends a section to AGENTS.mdcleanlist skill without --target prints the instructions. They tell the agent to:
- check sign-in with
cleanlist whoami; - use the main workflows below;
- show you every quote, including any CRM note, and only re-run with
--yesafter you approve; - write rows to files instead of printing them into the chat;
- branch on exit codes.
Then ask in plain language, for example: “Enrich leads.csv with work emails and save the result next to it. Show me the cost first.”
What you can do
# Enrich a CSV and write the enriched file
cleanlist enrich csv leads.csv --dry-run # cost only
cleanlist enrich csv leads.csv --yes -o leads.enriched.csv
# Find people at a set of companies (one domain per line), then save them
cleanlist people search --company-domains-file domains.txt --title "VP Sales" --json
cleanlist lists add "Q4 ABM" --from-task <task_id>
# Read and export lists
cleanlist lists
cleanlist lists rows "Q4 ABM" --all --format csv > q4.csv
cleanlist lists export "Q4 ABM" -o q4.csv
# Enrich a list, or one person
cleanlist enrich list "Q4 ABM" --scope full --yes --wait
cleanlist enrich person --linkedin https://www.linkedin.com/in/... --yes
# Fill an AI column on the first 10 rows
cleanlist smart-agents run "Q4 ABM" --column Hook --prompt "One-line opener about {{company}}" --rows 10 --yes --wait
# GTM agents: list them, read a run's records, turn one off
cleanlist agents list
cleanlist agents runs <agent_id>
cleanlist plays results <run_id> --wait
cleanlist agents off <agent_id>
# Anything Clu can do: list the actions, run one
cleanlist actions list
cleanlist actions run agents.get --args '{"agent_id":"..."}' --json
# Get events at your own URL (the signing secret is shown once)
cleanlist webhooks add https://example.com/hooks/cleanlist --events play_run.completed,reply.received
# Account
cleanlist credits
cleanlist usage --group-by toolLists can be named by id or by exact name. cleanlist --help lists every command, and cleanlist <command> --help shows its flags and examples.
| Command group | What it covers | Credits |
|---|---|---|
whoami, profiles, credits, usage | Who you’re signed in as, credit balance, price quotes, API usage | Free |
people search, people filters | Find People by title, seniority, function, location, industry, company size or company domain | No credits. Counts toward the search allowance |
lists … | List, read, create, rename and delete lists; add and remove people; import a CSV; export as CSV. lists delete and lists remove need an API key with the lists:delete opt-in | Free |
enrich person, company, list, task, csv | Work emails and phones for people, firmographics for companies, a whole list, the results of a search, or a CSV file | Normal prices. The quote shows the most a job can cost; work emails and phones are charged only when found |
smart-agents run, list, results | Smart agents such as Custom AI, Cold intro email and Company intel. Called agents run and agents results before 0.2.0 | Priced per row, shown in the quote |
agents list, get, create, update, off, runs, and plays results | GTM agents: list, create and edit them, turn one off, read their runs and each run’s records. Turning an agent on, running it now and setting its limits stay in the app | Free |
actions list, run, confirm | Clu’s own tools by group (lists, skills, agents, plays, sequences, crm), as actions | Each call is metered as in Clu; a card shows its cost first |
webhooks list, add, remove | Webhook subscriptions: send events to your own HTTPS URL | Free |
skill, mcp install | Install agent instructions; add the CluGTM MCP to Claude Code, Claude Desktop, Cursor or Codex | Free |
People search, lists, enrichment, smart agents, GTM agents, actions, webhooks and export are covered. CRM sync, company search, the Research and Qualification skills and Clu stay in the app or the MCP connector.
Quotes and approval
Every command that spends credits asks CluGTM for a quote first (POST /api/v2/credits/estimate), then:
| Situation | What happens |
|---|---|
| In a terminal | You see the cost and your balance, and answer Spend 242 credits? [y/N] |
--yes | Runs at the quoted cost |
No terminal and no --yes (a script or a coding agent) | Stops with exit code 7 and prints the quote as JSON. Show the cost to the person, then re-run with --yes |
--dry-run | Prints the quote and stops. Nothing is spent |
--max-credits N | Stops with exit code 5 if the quote is above N |
| Not enough credits | Stops with exit code 5 |
If your workspace pushes enriched people to HubSpot or Salesforce automatically, the quote includes a CRM note saying so. A quote lasts 5 minutes and works once.
actions run works the same way with a card instead of a quote. An action that spends, sends, deletes or writes to a CRM returns a card and runs nothing. --yes, or a yes at the prompt, confirms it; without a terminal it exits 7 with the card, and cleanlist actions confirm <card_id> --session <session_id> runs it once the person approves. --max-credits caps it. Sends, CRM writes and deletes also need the key’s opt-in scope (sequences:write, crm:write, lists:delete); without it they exit 3 with opt_in_scope_required. Turning an agent on, running it now and changing its limits exit 3 with person_required: a person does those in the app.
enrich csv imports the file into a list before it quotes, and the import is free. If you stop at the quote, re-running the same command reuses that list and doesn’t import the rows twice.
Output and exit codes
Output is a table in a terminal and JSON when piped. Choose with --json or --format table|json|jsonl|csv. Data goes to standard output and progress messages to standard error (-q hides them). Errors are JSON on standard error when piped, with a fix hint.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Unexpected or server error |
| 2 | Bad input: unknown flag, invalid value, or a list name that matches several lists |
| 3 | Not signed in, the sign-in was revoked, the plan has no API access, or a person must do it (person_required, opt_in_scope_required) |
| 4 | Not found |
| 5 | Not enough credits, or the quote is above --max-credits |
| 6 | Rate limited. A 429 exits straight away |
| 7 | Confirmation required: re-run with --yes once the cost is approved |
| 8 | --wait timed out and the job is still running. The error includes the command that resumes waiting |
--wait checks progress with a growing delay and follows the API’s retry hints. --timeout 10m sets how long to wait (30 minutes by default).
Only a GET is retried, up to 3 tries, on a 502, 503 or 504 or when no response comes back. A POST, PATCH or DELETE is sent once and never resent, so a write can’t run twice; when one gets no response, check before running it again.
Limits
The CLI shares the API’s rate limits: 60 requests a minute per workspace and 30 per API key. API keys can run 60 people searches a day, so avoid paging every result with people search --all in loops.
Environment variables
| Variable | Use |
|---|---|
CLEANLIST_API_KEY | API key. Overrides any saved sign-in |
CLEANLIST_PROFILE | Profile to use |
CLEANLIST_HOST | API base URL (default https://api.cleanlist.ai) |
CLEANLIST_CONFIG_DIR | Config folder (default ~/.config/cleanlist) |
CLEANLIST_NO_KEYCHAIN | Store credentials in the file, not the keychain |
Troubleshooting
| What you see | Why | Fix |
|---|---|---|
Not signed in. (exit 3) | No saved sign-in and no CLEANLIST_API_KEY | Run cleanlist login, or set CLEANLIST_API_KEY |
Invalid or expired API key (exit 3) | The key was revoked, expired or mistyped | Create a new key in Settings → API keys, or use cleanlist login |
| “Public API access is not included…” (exit 3) | The workspace’s plan has no API access, or it’s on a trial | Move to Pro or Enterprise in Settings → Plans & billing |
Confirmation required (exit 7) | A paid command ran without a terminal or --yes | Check the quote, then re-run with --yes |
opt_in_scope_required (exit 3) | A delete, send or CRM write with a sign-in or key that hasn’t opted into its scope | Tick the scope on an API key under Settings → API keys → Permissions and sign in with that key |
person_required (exit 3) | Turning an agent on, running it now or changing its limits | Do it in the CluGTM app |
agents run exits 2 and names smart-agents | AI-column commands were renamed in 0.2.0 | Use cleanlist smart-agents run |
More than one list is named … (exit 2) | Several lists share that name | Use the list id from cleanlist lists |
| Results or credits show up in the wrong workspace | The profile points at another workspace | Run cleanlist whoami, and use --profile or sign in again |
Still running; stopped waiting. (exit 8) | The job took longer than --timeout | Run the resume command from the error |
Still stuck? Email support@cleanlist.ai with the command you ran and the error.
Source and releases
The CLI is open source (MIT) at github.com/Cleanlist-ai/cleanlist-cli and published on npm as @cleanlist-ai/cli. cleanlist --version shows the installed version.