---
name: zergdesk-cli
description: Operate ZergDesk CRM and registered agent action queues through its first-party CLI, including BDR handoffs, human-approved outreach, scoped changes, capture and knowledge-base synchronization. Includes campaign cohorts, branching funnels and evidence-linked analytics. Use ZergBoard for software-feedback triage.
---

# ZergDesk CLI

ZergDesk supports sales, fundraising and custom projects. Use `zergdesk` (alias
`zdesk`) to operate its workspace CRM. Public discovery is at
https://zergdesk.com/agents.md. Read https://zergdesk.com/docs/cli.md for command
contracts and https://zergdesk.com/docs/api.md when using direct HTTP. For sales
fields, forecasting, stage history and feature boundaries, read
https://zergdesk.com/docs/sales-crm.md. These URLs work without a source checkout.

## Install and discover

Requires Node.js 22+ and npm. Install a pinned first-party tarball:

```sh
npm install --global https://zergdesk.com/downloads/cli/zergai-zergdesk-0.6.0.tgz
zdesk --version
zdesk --help
zdesk health
```

https://zergdesk.com/downloads/cli/latest.json provides release metadata,
`tarballUrl`, `sha256` and `integrity`. Registry publication is not required for
the direct tarball install; npm resolves its dependencies. Pin a version during
sync runs and upgrade between runs using the manifest's tarball URL. If the global
npm prefix is not writable, install with `--prefix "$HOME/.local"` and add
`$HOME/.local/bin` to `PATH`. The CLI's
`update` command currently targets the npm registry; use the public tarball path
for this release. `help GROUP` documents positional parameters and `routes
FILTER` lists the offline route catalog. A listed route may still require a
browser session.

## Credentials and scope

Have the user sign in to https://zergdesk.com with Zerg SSO, then create a token
in **Account → API tokens**, bound to the intended workspace and optionally a
project. Prefer `workspace:read,crm:read` for discovery. Request `crm:write` only
for authorized data changes and `workspace:write` for project administration.
Membership/role checks and plan limits remain in force. API tokens cannot create
workspaces, mint tokens or enter billing/SSO flows. Local password login and
recovery are retired.

Obtain the token through the agent host's secure secret form, secret manager or
private credential file, never chat. Use `ZDESK_API_TOKEN`, `--token-env NAME` or
`--token-file PATH`; there is no literal token argument. Token files must be
regular, nonsymlink, 0600 files containing a plain token or issued-token JSON.
The CLI leaves the source file intact. Do not extract browser cookies or create
administrative sessions as an access workaround.

```sh
export ZDESK_BASE_URL=https://zergdesk.com
# ZDESK_API_TOKEN comes from the host's secret manager.
zdesk auth configure --profile crm-agent
# Or use: zdesk auth configure --profile crm-agent --token-file /private/path/token.json
zdesk whoami --profile crm-agent
zdesk workspaces list --profile crm-agent
zdesk projects list WORKSPACE_SLUG --profile crm-agent
zdesk config set --profile crm-agent --workspace WORKSPACE_SLUG --project PROJECT_ID
```

Saved profiles are private and pinned to their origin. Set `ZDESK_PROFILE` or
pass `--profile` consistently; an isolated `--config PATH` is useful for another
actor. Never send a production credential to another origin. `config show`
reports context without exposing credentials. The user can revoke a token in
Account; local `auth logout` only forgets the saved credential.

`--workspace` is a **slug**; `--project` is a stable **ID** from `projects list`.
Project administration commands take project URL slugs separately. Firms are
sales accounts or investors, and people/firms are shared workspace records.
Deals and most workflow collections select a project; catalogs are workspace-wide.

## Inspect, export and reconcile

```sh
zdesk workspaces get WORKSPACE_SLUG --profile crm-agent
zdesk pipeline get --profile crm-agent
zdesk firms list --profile crm-agent --search 'Example' --field name
zdesk people list --profile crm-agent
zdesk opportunities list --profile crm-agent
zdesk crm export --profile crm-agent --include-sales --output desk-before.json
```

Read `workspace.plan`, `workspace.limits` and `workspace.usage` before imports.
`-1` means unlimited. Arrange required capacity through the browser/admin flow;
do not bypass a limit. Export to a new private path; existing files are refused.
`--include-sales` follows every page of activities, tasks, resources, catalogs,
views and sequences in addition to the pipeline snapshot.

Before a requested patch, fetch the record by ID and send only intended fields:

```sh
zdesk firms get FIRM_ID --profile crm-agent
zdesk firms update FIRM_ID --profile crm-agent --data @account-patch.json
zdesk people update PERSON_ID --profile crm-agent --data @contact-patch.json
zdesk opportunities update OPPORTUNITY_ID --profile crm-agent --data @deal-patch.json
zdesk activities create --profile crm-agent --data @meeting.json
zdesk tasks create --profile crm-agent --data @follow-up.json
```

Schemas reject unknown fields. Omitted fields are preserved; supplied arrays
replace arrays. Nullable dates use actual `YYYY-MM-DD` strings or `null` to
clear. Activity timestamps include an offset. Discover stage IDs from project
settings. Deal contact roles use `{personId,role}` and references must belong to
the tenant. Person private notes have separate admin access; workspace ownership
alone does not grant it. Shared account changes can affect another project.

For imports use `crm import firms|people|opportunities --file PATH --dry-run`,
review results, then omit `--dry-run` only for authorized writes. JSON and CSV are
supported, in batches of 500. Create base firms, then people, then firm contact
lists and dependent deals. `person.firmId` and `firm.contacts` are independent
links; reconcile both when the workflow uses both. Dry
runs do not save dependencies. Preserve a globally unique random ID and source
mapping before the first write; reruns must reuse it. Inspect each result because
batches can partially succeed. The CLI returns exit 4 on record failures.

Core CRM and sales records expose `version`, `updatedAt` and source `provenance`.
Use `--expected-version N` from the record you read; 0 means create only. HTTP 409
means another writer won: retain the authored change, fetch the current record
and review. Omitted preconditions retain legacy upsert behavior. The browser
editors and first-party sync use preconditions.

For knowledge-base reconciliation use `crm sync plan --file SOURCE.json --output
PLAN.json`, then inspect the plan before an authorized `crm sync apply --file
PLAN.json --output REPORT.json`. Input has `{records:[{entity,id,expectedVersion,
data,provenance?}]}`; `data` contains only intended writable fields. Plans pin the
origin, workspace and project. Apply skips conflicts/no-ops, never retries and
returns exit 4 if any record conflicts or fails. Persist returned versions with
the source mapping; do not advance a failed record's baseline. For incremental
pull use `crm changes --cursor CURSOR --limit 200`, follow `hasMore`, and save
`nextCursor` only after processing the page. Cursors are scope-bound. `crm
history ENTITY ID` reviews attributed snapshots; `crm restore --data @restore.json`
requires workspace admin rights and `{entity,id,historyId,expectedVersion}`.
No automatic Obsidian folder watcher is installed.

## Collateral and sales work

Use `activities`, `tasks`, `resources`, `catalogs`, `views`, `sequences` with
`list`, `create`, `update ID`; `views delete ID` deletes a saved view. Lists support
`--query firmId=ID`, `opportunityId`, `personId`, `kind`, `status`, `limit`, `offset`;
follow `pagination.hasMore`. Catalogs hold products, segments and competitors.
Resources link files or Markdown, including case studies and contract/invoice
metadata. They do not perform signing or payment collection. Sequences record
manual outreach plans and status; saving one does not send messages.

`decks create --data @deck.json` can take persistent random `id` and `versionId`.
`decks version-update --data @version.json` adds/patches versions.
`decks upload DECK_ID VERSION_ID --file deck.pdf` accepts PDF/PPTX up to 32 MiB;
PPTX conversion needs the server's Google integration. `dataroom upload --file
PATH --data @metadata.json` uploads general attachments. Scoped tokens support
these uploads. Share-link administration and analytics remain browser workflows.
Link attachments to accounts/deals with `resources` metadata and an authenticated
absolute download URL. Uploading does not make a file public.

`crm duplicates firms|people` returns candidates; `crm merge ENTITY SOURCE TARGET`
previews. Apply only an explicitly authorized merge after export and review;
`--apply` removes the source and requires workspace admin rights plus a
workspace-wide token. People merges also require private-note access.

## Connected work and daily queue

`records workspace firms|people|opportunities ID` returns linked activity, tasks,
documents, meetings and explicitly attributed deck engagement. `my-day` returns
due/overdue tasks, upcoming meetings, unanswered-email candidates and owned deals
missing a next step/date. Defaults are current-user assignment and UTC; add
`--query timeZone=America/Los_Angeles` or `--query assignment=all` where needed.
Reply candidates use known sender/recipient chronology; they do not prove that a
reply is required. Private capture is visible only to its connection owner.

Use `connections list`, `items ID`, `jobs ID` and `sync ID` to inspect health,
matching and durable job results. `sync` queues one job; poll jobs for completion.
To connect an authorized source, provide metadata in `--data @connection.json`
and its token separately with `--credential-env NAME` or a private
`--credential-file PATH`. No literal token JSON is accepted by these CLI commands.
Connections default to private. `visibility: workspace` explicitly publishes
unambiguous matches. Exact contact email matches are required; ambiguous/missing
matches remain in owner review. Gmail uses an existing Google account connected
in Desk Settings, selected by `accountId`, with no upstream token argument.
ZCal needs `resourceId` for the calendar. Companion sources use their scoped
read credentials, not the Desk token. Read the CLI guide for provider setup.

`connections update ID --data '{"enabled":false}'` pauses; `connections disconnect
ID` erases the stored connector credential and withdraws generated shared
metadata. This does not disconnect the user's Google account itself. Previously shared metadata remains in CRM history/change feeds; changing visibility does not retroactively purge it. Capturing
metadata never sends email, invites or recordings to another service.

## Results and boundaries

JSON results go to stdout; bounded JSON errors go to stderr. Exit codes: 0
success, 1 local I/O, 2 usage, 3 credentials, 4 API/payload failure, 5 network or
timeout. Mutations are never retried automatically. After an ambiguous timeout,
read by the persisted ID before repeating the write. A discovery request does
not authorize deletes, merges, outreach or private-file uploads.

`ztc ask` invokes the server-owned read-only CRM assistant. Model-provider
requests can include selected CRM context; use it for requested analysis.
Product feedback belongs in Desk's feedback capture UI; deck viewer comments and
CRM activities are not software-feedback tickets.

## Agent queues and concurrent BDR work

Read https://zergdesk.com/docs/action-queues.md before operating queues. Use
CLI 0.6.0 and pin that installed version for the run. Set workspace/project
profile defaults once; do not repeat flags on every call. Give each BDR and
channel agent a separate scoped Desk token/profile. Register the selected token
with `agents register --data '{"name":"Last-Mile BDR","capabilities":["research"]}'`,
retain its returned ID and send `agents heartbeat ID` while running. Do not
impersonate another agent or share its token. A Desk registration does not
supply channel credentials or authorize outbound messages.

Use `queues list` to select a function/account queue. Submit a stable
`idempotencyKey`, exact `recipient`, `type`, `subject`/`body`, optional source
`targetUrl` and linked CRM IDs with `actions create --data @request.json`.
Use `actions submit ID --expected-version N`. The designated channel agent can
`review` or `request-changes` with a reason. Watch `needs-work`, revise only the
intended fields with `actions update`, then resubmit. Never turn a request for
changes into permission to send.

Wait for the named human owner's approval in Desk. API tokens cannot approve,
reject or release uncertain work, even when issued by that owner. Do not extract
browser cookies, mint sessions or use `--session-env` as an agent workaround.
Approval covers one exact message/recipient revision and queue policy. The
executor claims approved work with `actions claim ID --expected-version N
--output NEW_PRIVATE_FILE`, then uses the returned canonical payload and live
lease for one attempt through its existing authorized channel tool. Complete
with a lease token and `receipt:{detail,externalId?,url?}`. Do not store provider
secrets in action text/history. A timeout may mean delivery happened: report
`fail` with a reason/lease, stop, and leave it uncertain for the human to inspect.
Never resend automatically. Human release requires fresh approval unless a
receipt verifies delivery already happened. Desk itself sends no outreach.

Poll `actions events --cursor CURSOR --limit 100`; follow `hasMore`, persist the
returned `cursor` only after processing, and fetch `actions get ID` before acting.
Read `actions history ID` for reasons/receipts. Mutations never retry; on 409
read current state and preserve your pending draft. Keep unapproved work queued.

Append observations using `notes append firms|people|opportunities ID --data
'{"body":"Observation","clientMutationId":"stable-key"}'`. Apply tag deltas
with `tags update firms|opportunities ID --data '{"add":["lane"],"remove":["old"]}'`.
These avoid concurrent whole-field replacements. Use `--expected-version` on
other writes. Match identities with `firms list --search Radiant --field name
--exact` and then use IDs. Firms support `ownerAgentId` plus existing `owner`;
people support `connectionDegree`, `outreachStatus`, `buyingSignalUrl`. Preserve
source links and report observations without inventing buying signals or proof
points. Continuous Desk updates do not change an external vault sync schedule.


## Campaigns, funnels and analyst briefs

Read https://zergdesk.com/docs/campaign-analytics.md when creating campaigns,
recording outcomes or interpreting a funnel. A segment is a classification;
a campaign is an explicit project cohort; a published funnel fixes a journey
and counting unit. Do not replace membership with a dynamic name search.
Contact, account and deal counts are different denominators, and overlapping
campaign totals do not add up to distinct project totals.

```sh
zdesk campaigns list
zdesk campaigns seed --output seed-preview.json
zdesk analytics overview
zdesk analytics funnel --query campaignId=CAMPAIGN_ID
zdesk analytics drilldown --query campaignId=CAMPAIGN_ID --query nodeId=NODE_ID
zdesk reports list
zdesk crm export --include-sales --include-campaigns --output desk-complete.json
```

Preview membership/seed reconciliation before authorized `--apply`, use exact
CRM IDs and current `--expected-version`, and leave unresolved matches for
review. Launch pins a funnel revision; subsequent edits must not rewrite the
cohort. Funnels support channel branches, joins and loops; current-field rules
are snapshot criteria, not dated progression. Preserve actual occurrence time
and provenance when using `observations record`; unknown dates stay null. Source
and sourceId identify an idempotent observation. `observations correct ID`
appends a correction rather than rewriting history. Do not infer acceptance,
human/qualified replies or held meetings from an approved/completed queue card.
Direct creation of a verified brand-new Desk deal records `opportunity.created`;
it does not establish qualification. Imports/sync and historical baselines do
not create that milestone; supply actual historical observations when known.

Report generation uses deterministic metrics and linked evidence. Review freshness,
coverage, cohort age and sample size before drawing comparisons. Analyst settings
require owner/admin. New proof-point approvals require a signed-in human
workspace owner/admin and an approval source URL; a token cannot grant sharing
permission. Recommendations cannot send messages or change observed CRM facts. Use the existing approval queues for
outbound work. `--include-campaigns` exports all pages of campaigns, funnels,
observations and reports plus published funnel revisions, merged-record identity aliases and analyst settings; `crm changes` supports subsequent
incremental pulls without turning old import timestamps into outreach events.


## Structured sales reporting, sync and introductions (0.6.0)

Read https://zergdesk.com/docs/prospect-sync.md before importing prospects or
using two-way editing, and https://zergdesk.com/docs/introductions.md for
relationship imports, paths and intro requests.

Sales Overview counts the explicit project prospect list independently of
campaign enrollment. Segments classify contacts in market/use-case taxonomies;
a primary lane is exclusive and owner groups are separate. Default outreach
statuses have stable IDs and explicit cumulative metric membership. A status
snapshot does not establish a dated acceptance, reply or meeting. Use
`analytics acquisition`, `analytics matrix`, `analytics accounts` and exact
record drill-downs; historical journeys remain under Campaigns.

Use `prospects list/get/update` with the prospect version. Project-scoped person
responses expose `outreachVersion`; changing the compatibility `outreachStatus`
requires `expectedOutreachVersion`. Keep workspace contact identity separate
from project outreach state. Next steps create linked tasks. DNC blocks outbound
queue work across projects; never remove DNC from the denominator to improve a rate.

For source-v2 synchronization, register a distinct `sources` instance with writer
location/version and persist its external-ID bindings. Prepare
`{schemaVersion:2,sourceId,runId,rows:[{externalId,personId,sourceRevision,fields}]}`
and use `crm sync plan/apply` with private output paths. Independent field edits
merge; competing edits remain durable conflicts. Desk-only edits become source
pull patches. Apply and verify them in the source before `sources ack`; an
unapplied pull must not advance the baseline. Never retry a mutation blindly.
A one-time legacy reconciliation does not establish a continuous writer; source
health remains awaiting adoption until the writer handshake succeeds. Source
omission does not authorize deletion, archival or campaign membership removal.

`prospects reconcile` previews exact source IDs, sequence membership, reviewed
aliases and explicitly selected activity backfills. Apply requires the preview
hash for the same data and mapping. Do not infer acceptance from messaged,
reply quality from a send, or historical timestamps from import time. Generic
campaign seeds require an explicit workspace template and preview token; they
contain no fixed company lanes or historical totals.

`relationships import` previews reviewed assertions between existing identities.
Private is the default. Network publication requires connector consent and a
human browser decision. `relationships paths` and `reach` use the same ACLs as
Desk and ZTC. Recorded chosen paths take priority; evidence of introductions,
committed money and accepted dated next steps determines ranking, never message
volume. Preserve legacy introPath decisions until explicitly reconciled.

An `intro-request` queue action addresses the connector and pins the request
version and path fingerprint. Queueing shares the message with its designated
sender/review audience, not the private network. A delivered request, connector
opt-in, target opt-in and completed introduction are separate evidence states.
Uncertain delivery is not retried. Human approval remains browser-only and
binds the viewed payload hash plus queue-policy version, including in batch
review. Tokens cannot grant/rebind sending authority or re-enable queues.

Use `conversations`, `signals` and `proofs` for state/next step, dated account
signals and resource-linked sharing permission. Internal approval and customer
permission are separate; wording/material edits invalidate approval. The
analyst's prose is interpretation, not permission or a verified numeric fact.
`crm export --include-sales-intelligence` includes permitted new collections,
source state and ACL-filtered history. Keep exports private and non-overwriting.
