npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zsign/cli

v0.1.1

Published

Command-line client for zSign — lint, send, and track e-signature envelopes.

Downloads

332

Readme

@zsign/cli

A thin command-line client for zSign — lint a PDF's signature fields, send it for signature, and track envelopes through completion, all from a terminal or a script.

Zero runtime dependencies. Requires Node 18+.

For a task-oriented walkthrough, start with the zSign CLI guide. This file is the complete command and behavior reference.

Install

npx @zsign/cli <command> ...

Or install it once:

npm install -g @zsign/cli
zsign <command> ...

Getting started

zsign init

init creates an account (or, with --email/--referral-code, attaches one) and writes an API key to ~/.zsign/config.json (mode 0600), alongside the base URL it was issued for. Every later command reads that file automatically — nothing else to configure.

To use an existing account instead of creating one, skip init and set the key yourself:

export ZSIGN_API_KEY=zs_live_...
zsign credits

Credential resolution order (highest priority first): --api-key flag, ZSIGN_API_KEY env var, the stored config file. --base-url / ZSIGN_BASE_URL resolve the same way, and default to https://zsign.io.

Self-hosting

Point the CLI at your own deployment with --base-url (or ZSIGN_BASE_URL):

zsign init --base-url https://zsign.your-domain.com

A stored key is only ever sent to the base URL it was issued for. Point the CLI anywhere else — --base-url, ZSIGN_BASE_URL — and the stored key is withheld: that call runs unauthenticated unless you pass a key explicitly with --api-key or ZSIGN_API_KEY. So neither a self-hosted credential nor a zsign.io one can be handed to a host you merely pointed at.

Plaintext http:// is refused unless the host is loopback or --insecure is passed explicitly.

Commands

init

Create an account and store its API key.

zsign init --email [email protected]

lint

Check a PDF's field tags before sending it — no credential required. Reports every tag found, the parties they belong to, and any syntax errors, exiting 5 if the document would be rejected.

zsign lint contract.pdf

The tag syntax itself is deliberately not restated here: it is defined in one place and served from it, at zsign.io/docs/api and GET /api/v1/field-syntax. Read it there so this page cannot drift out of date underneath you.

send

Send a PDF to one or more parties for signature. Each --to maps a party name (as tagged in the PDF) to a recipient.

zsign send contract.pdf --to "client=Alice <[email protected]>"

status

Check an envelope's status, or follow it live with --watch.

zsign status <document-id> --watch

--watch polls every 2 seconds; --interval <seconds> overrides it, accepting 1 to 3600.

fields

List a document's fields and their current values (unanswered fields report null, they aren't omitted).

zsign fields <document-id>

void

Cancel an in-progress envelope.

zsign void <document-id> --reason "sent by mistake"

download

Download the completed, signed PDF. Accepts either the original document id or the completed one — the CLI resolves it.

zsign download <document-id> --output signed.pdf

Pass --stdout instead of --output to stream the raw PDF bytes to stdout (cannot be combined with --json).

listen

Stream this account's webhooks to a local URL — no tunnel, no inbound port. The CLI long-polls a server-side queue and forwards each event to --forward-to with a real HMAC signature, exactly like a production webhook delivery.

zsign listen --forward-to http://localhost:3000/hooks

There is one listener per account. A second zsign listen for the same account from a different machine gets exit code 9 naming the machine that holds it; pass --replace to take over (this rotates the session secret, so the displaced listener's events stop verifying). Restarting zsign listen on the same machine after a crash reattaches to its own session instantly, without needing --replace.

Ctrl-C detaches the session but does not discard it — new events keep queueing, and everything already queued or delivered stays around for an hour, so a short restart doesn't lose anything the way a dropped tunnel would. Pass --discard-on-exit to delete the session and its retained events instead.

--retry retries the local handler on the production retry schedule when it returns a non-2xx — this is unrelated to --no-retry, which governs retrying zSign's own HTTP 429s. --fail-on-handler-error exits 8 on the first non-2xx response from your handler, instead of continuing to the next event.

Each event the CLI receives has its own event id, distinct from the id your production endpoint would get for the same business change — the two are independently delivered and acked copies, not the same delivery twice.

Signature verification is not restated here: it is defined in one place, at zsign.io/docs/webhooks, so this page cannot drift out of date underneath you.

replay

Re-deliver one retained webhook event, e.g. after fixing a bug in your local handler.

zsign replay <event-id> --forward-to http://localhost:3000/hooks

--forward-to is mandatory — replay does not remember a target from a previous listen session, since silently reusing one would be a footgun. replay neither acquires the listener lease nor changes the event's ack state, so it's safe to run alongside a zsign listen that's still running. It exits 8 if your handler rejects the redelivered event.

credits

Check your balance, or buy more. Available packs and prices come from your account, not from this document — run the command to see the current list.

zsign credits
zsign credits buy <pack>

help

Print the command list, global flags, and exit codes shown below.

zsign help

Not available yet

preview, whoami, and download --cert are not implemented in this release. If you need one of these, it's a known gap, not a bug — please don't file one.

--json

Every command accepts --json for machine-readable output. The envelope shape is a compatibility contract: fields may be added in a minor release, but never removed or retyped, so scripts should check for the keys they need rather than the whole object shape.

Success:

{ "ok": true, "...": "command-specific fields" }

Error:

{
  "ok": false,
  "error": {
    "code": "not_found",
    "http_status": 404,
    "message": "...",
    "detail": { }
  }
}

status --watch and listen always emit newline-delimited JSON (NDJSON) — one parseable JSON object per line, one line per status transition or forwarded event — regardless of --json, since both are streams and a consumer must never have to parse a partially-written array.

Global flags

| Flag | Meaning | | --- | --- | | --json | Emit the JSON envelope instead of human-readable text | | --api-key | API key for this call (overrides stored config / ZSIGN_API_KEY) | | --base-url | API base URL (overrides stored config / ZSIGN_BASE_URL) | | --no-retry | Disable automatic retry on HTTP 429 rate limiting | | --insecure | Allow plaintext http to a non-loopback host |

listen / replay flags

| Flag | Meaning | | --- | --- | | --forward-to <url> | Local URL to POST each event to (required) | | --replace | Take over a session another listener holds | | --retry | Retry the local handler on the production schedule (not --no-retry, which is about zSign's 429s) | | --fail-on-handler-error | Exit 8 on the first non-2xx from the local handler | | --discard-on-exit | Delete the session and its retained events on exit |

Exit codes

| Code | Meaning | | --- | --- | | 0 | Success | | 1 | Internal error | | 2 | Usage error / bad request (400) | | 3 | Authentication error (401/403) | | 4 | Insufficient credits (402) | | 5 | Validation failed (422) | | 6 | Not found (404) | | 7 | Rate limited (429) | | 8 | Handler failure (listen --fail-on-handler-error, or replay) | | 9 | Conflict (409) | | 130 | Interrupted (Ctrl-C) |