The Paragraph CLI covers the same ground as the REST API, with JSON output for scripts and agents and an interactive menu for everyone else.

Install

npm install -g @paragraph-com/cli

Requires Node.js 18 or later.

Sign in

paragraph login

This opens Paragraph in your browser, where you pick the publication to connect and approve access. To use an API key instead, pass it with --token, pipe it in with --with-token, or set PARAGRAPH_API_KEY:

paragraph login --token <your-api-key>
echo "<your-api-key>" | paragraph login --with-token
PARAGRAPH_API_KEY=<your-api-key> paragraph post list

Run paragraph whoami to check which publication you're using. Credentials are stored in ~/.paragraph/config.json.

Posts

New posts are drafts until you publish them.

paragraph post create --title "October update" --file ./draft.md
paragraph post list --status draft
paragraph post get <id-or-slug> --field markdown > post.md
paragraph post update <id-or-slug> --file ./updated.md
paragraph post publish <id-or-slug>
paragraph post publish <id-or-slug> --newsletter   # also email subscribers

post get accepts an ID, a URL, or @publication/slug. Other post commands include draft, archive, delete, test-email, feed, and by-tag, and destructive ones take --dry-run.

Drafted content

Short-form drafts (X posts and threads, LinkedIn posts, one-off emails, X Articles) go to the publication's library. Nothing is sent until someone sends it from the app.

paragraph content create --kind tweet --title "Launch thread" --tweet "First." --tweet "Second."
paragraph content list --kind tweet --status draft

See Drafted content for every kind, how to group drafts with the post they came from, and the content commands that edit, archive, and restore them.

Publications, search, and subscribers

paragraph publication get @your-publication
paragraph search post --query "release notes"
paragraph subscriber list --limit 100
paragraph subscriber add --email reader@example.com
paragraph subscriber import --csv subscribers.csv

Run paragraph --help for every command, or paragraph <command> --help for its flags.

Scripts and agents

Every command takes --json. Data goes to stdout and status messages to stderr, so output pipes cleanly:

paragraph --json post list | jq '.data[0].title'

Lists return { "data": [...], "pagination": { "cursor": "...", "hasMore": true } }, and single items return the object itself. In --json mode, errors are JSON on stderr with a non-zero exit code:

{ "error": "Not found.", "code": "NOT_FOUND", "status": 404 }

code is one of UNAUTHORIZED, FORBIDDEN, NOT_FOUND, RATE_LIMITED, SERVER_ERROR, REQUEST_FAILED, CLIENT_ERROR, or UNKNOWN.

Outside a terminal, delete requires --yes. Set PARAGRAPH_NON_INTERACTIVE=1 or CI=true to turn off the interactive menu, and PARAGRAPH_API_URL to point at a different API.

To teach a coding agent the CLI, install the Paragraph CLI skill.

Interactive mode

Run paragraph with no arguments for a menu-driven interface with scrollable lists and keyboard navigation. It's skipped automatically when output is piped or --json, --help, or --version is passed.

Source

The CLI is open source on GitHub and published to npm.

On this page