NewSee how
FirstSales
Home/Tutorials/FirstSales CLI Quickstart
Developer & CLI

FirstSales CLI Quickstart

Install the FirstSales CLI, authenticate with an API key, and run your first safe commands — whoami, org/workspace discovery, dry-run, and idempotency.

8 min read·Advanced·7 steps
  1. 1

    Install the CLI

    The FirstSales CLI is an npm package. Install it globally to get the firstsales binary:

    npm install -g @firstsales.io/cli
    firstsales --version
  2. 2

    Authenticate

    Create a Developer API key in Settings → API, then give the CLI the key and base URL. The cleanest way is environment variables:

    export FIRSTSALES_API_KEY="fs-key-..."
    export FIRSTSALES_BASE_URL="https://api.app.firstsales.io"
  3. 3

    Verify with whoami and doctor

    Before doing anything, confirm the key resolves to the right context. whoami shows your user, org, and workspace; doctor checks your setup:

    firstsales whoami --json
    firstsales doctor
  4. 4

    Understand the global flags

    Every command shares the same flags — learn these once:

    • --org <id> / --workspace <id> — target scope (most commands need both).
    • --json (default) / --pretty — output format.
    • --data '<json>' / --data-file <path> — request body.
    • --idempotency-key <key> — safe retries on creates.
    • --dry-run — preview the request without sending it.
    • --confirm — required for any destructive (delete) command.
    • --api-key / --base-url / --profile — override auth per call.
  5. 5

    Discover your org and workspace

    Most commands are scoped to an org and workspace. List them, then reuse the IDs:

    firstsales organizations list
    firstsales workspaces list --org ORG_ID
    firstsales campaigns list --org ORG_ID --workspace WS_ID
  6. 6

    Make a safe first mutation

    Follow the golden loop: inspect first, mutate deliberately, verify after. Preview with --dry-run, then create with an idempotency key, then re-read to confirm:

    # Preview — no write happens
    firstsales contacts create --org ORG_ID --workspace WS_ID \
      --data '{"email":"jane@acme.com","first_name":"Jane"}' --dry-run
    
    # Create for real, idempotently
    firstsales contacts create --org ORG_ID --workspace WS_ID \
      --data '{"email":"jane@acme.com","first_name":"Jane"}' \
      --idempotency-key jane-acme-2026-01
    
    # Verify
    firstsales contacts list --org ORG_ID --workspace WS_ID
  7. 7

    Delete deliberately

    Destructive commands refuse to run without --confirm — this is intentional friction so an agent or a fat-fingered command can't wipe data by accident:

    firstsales contacts delete --org ORG_ID --workspace WS_ID \
      --contact CONTACT_ID --confirm

Pro tips

Hard-won shortcuts that keep warm-up on track.

1

Inspect first, mutate deliberately, verify after

The CLI is built around this loop. List before you change, --dry-run the change, run it, then re-read to confirm. It's slower to type and far cheaper than undoing a bad write.

2

--json is for machines, --pretty is for you

Output defaults to compact JSON so scripts and agents can parse it. Add --pretty when a human is reading, but keep --json in pipelines.

3

Never echo your key

Pass auth via FIRSTSALES_API_KEY or a profile, not inline where it lands in shell history or logs. The CLI never prints raw keys — don't undo that by echoing the env var.

4

Idempotency keys are free insurance

Any create that might be retried should carry --idempotency-key. A replayed command becomes a no-op instead of a duplicate.

Frequently asked questions

How do I install the CLI?

npm install -g @firstsales.io/cli, which gives you the firstsales binary. It maps directly to the public /api/v1 Developer API.

How does authentication work?

Set FIRSTSALES_API_KEY (and optionally FIRSTSALES_BASE_URL) in your environment, or pass --api-key / --base-url per command. Verify with firstsales whoami --json.

Why do commands need --org and --workspace?

Resources are scoped to an organization and workspace. List them with organizations list and workspaces list --org ORG_ID, then pass both IDs on scoped commands.

What does --dry-run do?

It prints the request the CLI would send without actually sending it — so you can confirm the body and target before a real mutation.

Why won't my delete run?

Destructive commands require the --confirm flag by design. Add --confirm once you're sure — it's the safety catch that stops accidental deletions.

Is the CLI different from the API?

It's a thin wrapper over the same public /api/v1 endpoints. The CLI adds convenience — centralized auth, stable JSON, idempotency handling, and destructive-op confirmation — so agents and scripts don't reimplement it.

Can I keep multiple accounts configured?

Yes — use --profile <name> to load a saved local profile, or override --api-key/--base-url per command to switch between orgs or environments.

Ready to put this into practice?

Start your FirstSales trial and launch a warmed, authenticated mailbox in minutes.

Start for $1