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.
Cleanlist CLI
The Cleanlist CLI is the cleanlist command. It runs Cleanlist from a terminal, a script or a coding agent: search people, enrich CSVs and lead lists, run smart agents (AI columns), and export lists. 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 Cleanlist 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 18.18 or later.
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 Cleanlist 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 reach your account settings, billing or API keys. The CLI refreshes the sign-in on its own, and cleanlist logout signs out and revokes it.
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 agents run "Q4 ABM" --column Hook --prompt "One-line opener about {{company}}" --rows 10 --yes --wait
# 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 | 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 |
agents run, agents results | Smart agents such as Custom AI, Cold intro email and Company intel | Priced per row, shown in the quote |
skill | Install agent instructions | Free |
People search, lists, enrichment, smart agents and export are covered. CRM sync, company search, Skills (Research, Qualification), Agents, Sequences and Clu stay in the app or the MCP connector.
Quotes and approval
Every command that spends credits asks Cleanlist 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.
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, or the plan has no API access |
| 4 | Not found |
| 5 | Not enough credits, or the quote is above --max-credits |
| 6 | Rate limited (after automatic retries) |
| 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).
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 |
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 (opens in a new tab) and published on npm as @cleanlist-ai/cli (opens in a new tab). cleanlist --version shows the installed version.