Fast, script-friendly Zendesk CLI for searching tickets, reading ticket threads, performing safe private handoffs, and downloading screenshots/attachments.
Inspired by the UX style of gogcli and wacli:
- clean command tree
- JSON-first automation support
- human-readable terminal output by default
- stable TSV output for shell pipelines
- saved accounts/profiles
- secure secret storage via OS keyring
The project is already usable for read workflows plus a small safe write workflow:
- authenticate with API token or imported OAuth access token
- search tickets by Zendesk query syntax or friendly flags
- inspect ticket metadata
- read comments / conversation history
- inspect audits
- list and download screenshots / attachments
- look up groups and users to build queries
- reassign a ticket to a different team/group
- add an internal note that is always sent as private
Public replies are intentionally not supported by this workflow unless code explicitly opts into them. See docs/spec.md for the broader roadmap.
- Tickets
- search by status / assignee / group / tags / dates
- fetch ticket metadata
- fetch ticket tags only
- fetch full ticket content
- fetch comments only
- fetch audits only
- reassign a ticket to a different team / group
- add private internal notes
- list and download attachments
- print browser URLs for tickets
- Auth
- saved profiles/accounts
- API token auth
- imported OAuth bearer token auth
- secrets stored in OS keyring
- Helpers
- list groups and group members
- search users and list user groups
- Automation-friendly output
--jsonfor machine-readable output--plainfor stable TSV output
Choose one of the following options.
git clone <your-repo-url>
cd zencli
makeThis builds the binary to:
./bin/zengo build -o ./bin/zen ./cmd/zenRun:
./bin/zen --helpYou need:
- Zendesk subdomain, such as
acmeforhttps://acme.zendesk.com - account email
- API token
API tokens are created in Zendesk Admin Center and typically require admin access.
See docs/auth.md for details.
zencli currently supports importing an existing OAuth bearer token.
It does not yet implement the full browser OAuth login / refresh-token flow.
./bin/zen auth add work \
--subdomain acme \
--email you@example.com \
--auth api_tokenThis prompts for the token securely and stores it in your keychain.
./bin/zen auth add work-oauth \
--subdomain acme \
--auth oauth_token./bin/zen auth add work \
--subdomain acme \
--email you@example.com \
--api-token "$ZENDESK_API_TOKEN"
./bin/zen auth add work-oauth \
--subdomain acme \
--oauth-token "$ZENDESK_OAUTH_TOKEN"./bin/zen auth test work./bin/zen --account work tickets search --group "Support" --status open
./bin/zen --account work search --assignee me --tag billing --status open
./bin/zen --account work tickets search --raw-query 'type:ticket status<solved group:"Extract"'./bin/zen --account work tickets content 12345
./bin/zen --account work read 12345./bin/zen --account work tickets tags 12345
./bin/zen --account work --json tickets tags 12345./bin/zen --account work tickets attachments list 12345 --include-inline-images
./bin/zen --account work tickets attachments download 12345 --include-inline-images --only-imagesIn Zendesk, “team” usually maps to a group.
./bin/zen --account work tickets update 12345 \
--team "Tier 2" \
--note "Handing off to Tier 2 for deeper investigation."Use --note-file for longer private notes:
./bin/zen --account work tickets update 12345 \
--team "Tier 2" \
--note-file ./handoff-note.txtIn Zendesk, “team” often maps to a group.
./bin/zen --account work tickets search --group "Extract"./bin/zen --account work tickets search --assignee "Extract Team"./bin/zen --account work tickets update 12345 \
--team "Extract" \
--note "Internal handoff: please pick this up for the next investigation step."./bin/zen --account work tickets content 12345 --include-inline-images
./bin/zen --account work tickets attachments download 12345 --include-inline-images --only-images./bin/zen \
--subdomain acme \
--email you@example.com \
--api-token "$ZENDESK_API_TOKEN" \
tickets search --status openDefault output is human-friendly.
./bin/zen --account work --json tickets get 12345./bin/zen --account work --plain tickets attachments list 12345Top-level help:
./bin/zen --helpCommand help:
./bin/zen tickets --help
./bin/zen tickets search --help
./bin/zen tickets content --help
./bin/zen auth add --helpMake shortcut:
make zen -- --help
make zen -- tickets search --helpSupported global env vars:
ZEN_ACCOUNTZEN_SUBDOMAINZEN_EMAILZEN_API_TOKENZEN_OAUTH_TOKENZEN_COLORZEN_JSON=1ZEN_PLAIN=1ZEN_KEYRING_PASSWORD
Examples:
export ZEN_ACCOUNT=work
./bin/zen tickets search --status open
export ZEN_SUBDOMAIN=acme
export ZEN_EMAIL=you@example.com
export ZEN_API_TOKEN=...
./bin/zen tickets get 12345docs/spec.md— product / architecture specdocs/usage.md— command guide and examplesdocs/auth.md— auth setup and security notesdocs/development.md— local development workflowdocs/releasing.md— tagging and release workflowCHANGELOG.md— release notes
cmd/zen/ binary entrypoint
internal/cmd/ command definitions
internal/config/ saved account metadata
internal/secrets/ keyring-backed secrets
internal/zendeskapi/ Zendesk HTTP client and response types
internal/outfmt/ output helpers
Build, test, and lint:
make build
make test
make fmt
make lint
make ciRun the local binary:
make zen -- tickets search --status open- write support is intentionally narrow: only team/group reassignment and private internal notes
- no public reply flow yet
- no browser-based Zendesk OAuth login flow yet
- saved OAuth auth currently stores an imported bearer token only
- no Homebrew tap / package publishing configured yet
- no shell completion command yet
- API tokens and OAuth tokens are sensitive secrets; prefer passing them through the keychain-backed
auth addflow - Zendesk API token permissions are effectively limited by the user role you authenticate as
- for truly lower-privilege testing, use a lower-privilege Zendesk user rather than an admin-backed token
tickets updateonly creates private/internal notes; public replies require explicit code-level approval and are not exposed in the CLI flow- when downloading attachments,
zenclionly forwards Zendesk auth to the Zendesk host itself
MIT. See LICENSE.