CLI | Paragraph Docs
CLI
Manage posts, publications, subscribers, and coins from the command line. Built for humans, agents, and CI.
The Paragraph CLI is a command-line tool for managing posts, publications, subscribers, and coins. It works for both human and programmatic (agent) usage.
Prerequisites: Node.js version 18 or higher (not needed for the Homebrew install).
Install
npm
npm install -g @paragraph-com/cli
Homebrew
brew tap paragraph-xyz/tap && brew install paragraph
Authentication
Get your API key in the app at app.paragraph.com under Settings -> Publication -> Developer.
Authenticate
paragraph login
Or provide the key directly:
paragraph login --token <your-api-key>
Verify
paragraph whoami
For CI or agent environments, you can pipe the token or set an environment variable:
echo "<your-api-key>" | paragraph login --with-token
PARAGRAPH_API_KEY=<your-api-key> paragraph post list
Credentials are stored in ~/.paragraph/config.json (mode 0600).
Quick examples
paragraph post create --title "My Post" --file ./draft.md
paragraph post publish my-post
paragraph post list
paragraph search post --query "ethereum"
Run paragraph --help for all commands, or paragraph <command> --help for details on any command.
Using an AI agent like Claude Code or Cursor? Install the Paragraph CLI skill to teach it how to use the CLI:
npx skills add paragraph-xyz/skill --skill paragraph-cli
Command reference
Posts
List posts
paragraph post list
paragraph post list --status draft
paragraph post list --limit 50 --cursor <cursor>
# List posts from any publication (public, no auth required)
paragraph post list --publication <id-or-slug>
Get a post
Accepts an ID, URL, or @publication/slug:
paragraph post get <post-id>
paragraph post get @yearn/some-post-slug
paragraph post get https://paragraph.com/@yearn/some-post-slug
Extract a single field (raw value to stdout, pipeable):
paragraph post get <id> --field markdown > post.md
paragraph post get <id> --field title
Create a post
Creates a draft by default:
paragraph post create --title "My Post" --text "# Hello World"
paragraph post create --title "My Post" --file ./draft.md
cat draft.md | paragraph post create --title "From Stdin"
paragraph post create --title "Post" --text "Content" --subtitle "Summary" --tags "web3,defi"
Update a post
paragraph post update <id-or-slug> --title "New Title"
paragraph post update <id-or-slug> --file ./updated.md --tags "new,tags"
Post lifecycle
paragraph post publish <id-or-slug>
paragraph post publish <id-or-slug> --newsletter # publish + email subscribers
paragraph post draft <id-or-slug> # revert to draft
paragraph post archive <id-or-slug>
Preview and test
paragraph post publish <id-or-slug> --dry-run
paragraph post delete <id-or-slug> --dry-run
paragraph post test-email <id> # send test email (drafts only)
Delete a post
paragraph post delete <id-or-slug>
paragraph post delete <id-or-slug> --yes # skip confirmation
Browse posts
paragraph post by-tag defi --limit 20
paragraph post feed --limit 10
Shortcuts
Top-level shortcuts for common operations:
paragraph create --title "Quick Post" --text "Content"
paragraph update my-post-slug --title "Updated"
paragraph delete my-post-slug --yes
Publications
paragraph publication get @variantwriting
paragraph publication get blog.variant.fund
paragraph publication get <publication-id>
Search
paragraph search post --query "ethereum"
paragraph search blog --query "web3"
Subscribers
paragraph subscriber list --limit 100
paragraph subscriber count <publication-id>
paragraph subscriber add --email user@example.com
paragraph subscriber add --wallet 0x1234...abcd
paragraph subscriber import --csv subscribers.csv
Coins
paragraph coin get <id-or-address>
paragraph coin popular --limit 10
paragraph coin search --query "test"
paragraph coin holders <id-or-address> --limit 50
paragraph coin quote <id-or-address> --amount <wei>
Users
paragraph user get <user-id>
paragraph user get 0x1234... # by wallet address
Agent and programmatic usage
The CLI is designed for use by AI agents and scripts.
JSON output
All commands support --json. Data goes to stdout, status messages to stderr:
paragraph --json post list | jq '.data[0].title'
paragraph --json post get <id> | jq '.markdown'
paragraph --json search post --query "web3" | jq '.length'
Paginated commands return:
{ "data": [{ "id": "...", "title": "..." }], "pagination": { "cursor": "abc123", "hasMore": true }}
Single-item commands return the object directly:
{ "id": "...", "title": "...", "markdown": "..." }
Structured errors
In --json mode, errors are structured JSON on stderr with a non-zero exit code:
{ "error": "Not found.", "code": "NOT_FOUND", "status": 404 }
Error codes: UNAUTHORIZED, FORBIDDEN, NOT_FOUND, RATE_LIMITED, SERVER_ERROR, REQUEST_FAILED, CLIENT_ERROR, UNKNOWN.
Non-interactive safety
deleterequires--yesin non-TTY environmentsloginsupports--with-tokenfor stdin piping and--tokenfor direct input- Destructive commands support
--dry-run - Set
PARAGRAPH_NON_INTERACTIVE=1orCI=trueto force CLI mode
Environment variables
| Variable | Purpose |
|---|---|
PARAGRAPH_API_KEY |
API key (alternative to login) |
PARAGRAPH_API_URL |
Custom API base URL |
PARAGRAPH_NON_INTERACTIVE |
Set to 1 to disable TUI |
CI |
Set to true to disable TUI |
Interactive TUI
Running paragraph with no arguments launches an interactive terminal UI with menus, scrollable lists, and keyboard navigation.
The TUI is disabled automatically when:
--json,--help, or--versionflags are used- stdout is not a TTY (e.g., piped output)
CI=trueorPARAGRAPH_NON_INTERACTIVE=1is set
Resources
[**View on GitHub**
Explore the source code or report issues.](https://github.com/paragraph-xyz/paragraph-cli) [**npm package**
View on npm.](https://www.npmjs.com/package/@paragraph-com/cli)
[TypeScript SDK
Install the Paragraph SDK and query publications, posts, coins, and user profiles with full type safety.](https://docs.paragraph.com/developers/sdk) [MCP server
Connect AI agents to Paragraph via the Model Context Protocol.](https://docs.paragraph.com/developers/mcp)