Skip to content
NewSee how

Using FirstSales with Claude Code

Drive FirstSales from Claude Code through the CLI. Install, authenticate, inspect before mutating, and never expose your API key in the agent's output.

  1. Why the CLI for Claude Code

    Claude Code has shell access, so it should drive FirstSales through the CLI, not raw HTTP. The CLI centralizes authentication, returns stable JSON the agent can parse, handles idempotency headers, and forces confirmation on destructive operations: everything you'd otherwise have to prompt the agent to do correctly every time.

    Rule of thumb from the docs: agents should prefer the CLI when shell access exists.

  2. Install and expose the key

    Install the CLI once, and give Claude Code the key through the environment so it never appears in a prompt or transcript:

    npm install -g @firstsales.io/cli
    export FIRSTSALES_API_KEY="fs-key-..."   # set in your shell, not in the chat
  3. Give the agent its operating rules

    Paste a short operating contract into Claude Code (or a project rules file) so it behaves safely:

    • Start every session with firstsales whoami --json; confirm org and workspace before acting.
    • Inspect first, mutate deliberately, verify after.
    • Use --idempotency-key on any create that might be retried.
    • Use --confirm only for an intentional delete the user asked for.
    • Never print raw API keys.
  4. Read-only exploration is always safe

    Encourage the agent to explore with list/get commands freely: they can't damage anything:

    firstsales campaigns list --org ORG_ID --workspace WS_ID --json
    firstsales contacts list --org ORG_ID --workspace WS_ID --json
    firstsales billing overview --org ORG_ID --json
  5. Mutations: preview, act, verify

    For anything that writes, have Claude Code follow the loop end to end: --dry-run, then the real call with an idempotency key, then a re-read:

    firstsales contacts create --org ORG_ID --workspace WS_ID \
      --data '{"email":"[email protected]","first_name":"Sam"}' --dry-run
    
    firstsales contacts create --org ORG_ID --workspace WS_ID \
      --data '{"email":"[email protected]","first_name":"Sam"}' \
      --idempotency-key sam-acme-2026-01
    
    firstsales contacts list --org ORG_ID --workspace WS_ID --json
  6. Approve or reject AI drafts from the terminal

    A useful Claude Code loop: review pending AI-written replies and act on them without opening the app. List threads, read one, then approve or reject the draft:

    firstsales inbox threads --org ORG_ID --workspace WS_ID
    firstsales inbox thread --org ORG_ID --workspace WS_ID --thread THREAD_ID
    firstsales inbox approve-draft --org ORG_ID --workspace WS_ID \
      --email EMAIL_ID --idempotency-key approve-EMAIL_ID
  7. Respect the public surface

    Tell the agent to stay on the CLI's public commands. If a command returns unsupported_operation, it must stop and report: not try to call app-private routes, provider callbacks, tracking pixels, unsubscribe handlers, or internal cron endpoints to force the result.

Pro tips

  • Put the operating rules in a project rules file

    Rather than re-pasting the safety contract each session, drop it in your Claude Code project rules so every run starts with whoami and the inspect-mutate-verify loop.

  • Key in the environment, never in the chat

    Export FIRSTSALES_API_KEY in the shell Claude Code runs in. If the key is in a prompt, it's in the transcript: the CLI keeps it out of output, don't put it back in.

  • Let it read freely, gate the writes

    list/get/analytics commands are safe to run unsupervised. Reserve your review for anything with create/update/delete or --confirm.

  • unsupported_operation means stop

    Train the agent to treat unsupported_operation as a wall, not a puzzle. The public CLI is the whole allowed surface; there is no clever workaround worth the risk.

Frequently asked questions

Should Claude Code use the CLI or the API?

The CLI. Because Claude Code has shell access, the CLI is preferred: it centralizes auth, emits stable JSON, and enforces idempotency and destructive-op confirmation so the agent doesn't have to reimplement those.

How do I keep my API key out of the transcript?

Export FIRSTSALES_API_KEY in the shell before starting Claude Code, and instruct it never to print raw keys. The CLI reads the env var and never echoes it in output.

What's the safe workflow for changes?

Verify identity with whoami, confirm org/workspace, inspect current state, make the minimal change with --dry-run then --idempotency-key, use --confirm only for intended deletes, and re-read to validate.

Can it manage the inbox?

Yes: inbox threads, inbox thread, and inbox approve-draft / reject-draft let Claude Code triage and act on AI-written replies from the terminal.

What if a command isn't supported?

If the CLI returns unsupported_operation, the agent should stop and report it. It must not fall back to app-private routes, callbacks, pixels, or cron endpoints: those are off-limits and will break.

How do I stop accidental deletions?

Destructive commands require --confirm. As long as the agent only adds --confirm for deletions the user explicitly asked for, an accidental wipe can't happen silently.

Developer & CLI

Outreach that keeps going after you log off.Leads, emails, follow-ups and replies, handled.

Connect unlimited mailboxes and let AI agents find leads, write each email and follow up. Or send your own templates in manual mode. From $29/mo.

$1 for 3 days · Cancel anytime · No contract

Install with AI

Your coding agent sets up the FirstSales CLI and skills for you.

Prompt for Claude Code

I'm setting up FirstSales (https://firstsales.io), an AI outbound sales platform: campaigns, contacts, a reply inbox, deliverability and lead signals. Help me get my workspace sending real, good emails end to end, from Claude Code.

Read these first so you know how FirstSales works:
- Developer docs and API: https://developer.firstsales.io
- CLI: https://www.npmjs.com/package/@firstsales.io/cli
- Skills for coding agents: https://github.com/firstsalesio/firstsales-skills (read README.md and GUIDE.md)

Setup
1. Install the CLI: npm install -g @firstsales.io/cli
2. Install the FirstSales skills:
   claude plugin marketplace add firstsalesio/firstsales-skills
   claude plugin install firstsales@firstsales
3. Ask me if I already have a FirstSales account. If not, send me to https://app.firstsales.io to sign up.
4. Ask me to create an API key under Settings → API → API Keys, with only the scopes we need.
   Never ask me to paste the key into this chat. Tell me to run this in my own terminal, so the key stays hidden:
   read -rs FS_KEY && firstsales auth login --api-key "$FS_KEY"; unset FS_KEY
5. Run `firstsales whoami` and tell me which workspace and organisation we are connected to.

Then ask me about my business: what I sell, who I sell to (roles, company size, countries), my best customers, and what I use today for outbound (tools, lists, mailboxes). Walk me through:
1. Teaching FirstSales my business: website, offer, proof points and case studies in the knowledge base, so the AI writes like someone who knows the product.
2. Connecting my sending mailboxes and checking my sending domain: SPF, DKIM, DMARC and warm-up. If anything is unhealthy, tell me the exact DNS record to add.
3. Bringing in contacts: import my CSV or CRM export into a clean list, remove duplicates and bad emails, and block domains I must never email (customers, competitors, my own).
4. Building my first campaign: the right list, senders, steps and timing. Write the sequence with me, show me the drafts, and do not launch until I say yes.
5. Setting up Signals if it fits: find people engaging with LinkedIn posts about topics my buyers care about, and turn them into leads.
6. Inviting my team and giving each person the right access.

Once campaigns run, show me how to work the reply inbox from here: which replies need an answer, draft responses in my voice, and move good conversations into deals. If I use Cal.com, connect it so follow-ups can offer my booking link (not the first email).

Throughout, as you learn about my business, proactively suggest and help create:
- Reply templates for the questions and objections my prospects are likely to raise, based on my product, site and codebase if you can see them.
- Campaign ideas and segments worth testing, with the reason for each.

Safety rules:
- Show every change as a dry run (--dry-run) first and wait for my yes. Never send emails, launch campaigns or delete anything without my yes.
- Tell me before anything that spends credits, and how many.

Be opinionated. If the docs give a sensible default, just use it. Don't make me choose between five options.