CLI
Use the first-party CLI for trusted publishing, editorial automation, smoke tests, and offline demos.
The @cli-blog/cli package is the supported command-line tool for the public Cli Blog content API. It manages posts, authors, media, categories, tags, locales, sitemap XML, feed XML, revisions, and slug redirects.
What is this?
Use the CLI when you want terminal-first publishing, CI automation, smoke tests, or agent-safe editorial workflows. It uses the first-party Node SDK internally, supports JSON output, and keeps saved local config restricted to the current OS user.
The CLI does not expose dashboard-only settings, billing, audit, admin, or API-key helper routes.
Getting started
Run a demo command if you want to inspect CLI output before using a key:
npx @cli-blog/cli posts list --demo --jsonCreate sample content with demo output:
npx @cli-blog/cli posts create --demo --title "Hello from demo mode"Fetch sample feed XML:
npx @cli-blog/cli feed get --demoInstall it globally:
npm install -g @cli-blog/cliConfigure a trusted API key:
cli-blog config set --api-key "$CLI_BLOG_API_KEY"Environment variables override saved config and are preferred for CI and shared shells:
CLI_BLOG_API_KEY=<private-api-key>Use public keys for published-content reads. Use private keys only in trusted shells, CI, servers, or agent environments. Avoid passing private keys through --api-key because command arguments may be retained in shell history or exposed through local process inspection.
Reference
Global options:
| Option | Description |
|---|---|
--api-key <key> | API key override. Prefer CLI_BLOG_API_KEY for private keys. |
--demo | Return offline demo content without setup. |
--json | Print formatted JSON. |
--yes | Skip confirmation prompts for destructive real API commands. |
--version | Print the installed CLI version. |
Commands:
| Command | Purpose |
|---|---|
config set | Save CLI configuration. |
version | Print the installed CLI version. |
posts list | List posts. |
posts get | Retrieve one post. |
posts related | Retrieve ranked related posts with a recent-post fallback. |
posts create | Create a post. |
posts update | Update a post. |
posts publish | Convenience shortcut for setting status to published. |
posts schedule | Convenience shortcut for setting status to scheduled with a date. |
posts delete | Delete a post. |
posts revisions list | List post revision snapshots. |
posts revisions get | Retrieve a post revision snapshot. |
posts redirects get | Resolve historical post slugs. |
authors list | List author profiles. |
authors get | Retrieve one author profile. |
authors create | Create an author profile. |
authors update | Update an author profile. |
authors delete | Delete an author profile. |
media list | List media assets. |
media get | Retrieve one media asset. |
media upload | Upload a media asset. |
media update | Update media metadata. |
media delete | Delete a media asset. |
categories list | List categories. |
categories get | Retrieve one category. |
categories create | Create a category. |
categories update | Update a category. |
categories delete | Delete a category. |
tags list | List tags. |
tags get | Retrieve one tag. |
tags create | Create a tag. |
tags update | Update a tag. |
tags delete | Delete a tag. |
locales list | List supported BCP 47 locale tags. |
sitemap get | Fetch sitemap XML. |
feed get | Fetch feed XML. |
Post workflow is status-based. posts create defaults to draft when --status is omitted, and posts update can set --status directly. posts publish and posts schedule exist to make the common transitions easier to type and clearer in scripts.
Examples
Fetch related posts for an article page:
cli-blog posts related release-notes \
--locale en-US \
--limit 4 \
--fields summary \
--include authors,media \
--jsonShared tags, categories, and authors rank first. If fewer than four posts match those relations, the API fills the response with the newest published posts in the same locale. The returned items use the normal post shape and do not include internal ranking scores.
Create publishing resources:
cli-blog authors create --public-name "Maya Chen" --bio "Field notes from San Francisco" --jsoncli-blog categories create --name "San Francisco" --locale en-US --jsoncli-blog tags create --name "city-notes" --locale en-US --jsonCreate and publish a post:
cli-blog posts create \
--title "A developer's guide to San Francisco" \
--body-markdown ./post.md \
--author-ids author_123 \
--category-ids term_category_123 \
--tag-ids term_tag_123 \
--seo-title "A developer's guide to San Francisco" \
--json
cli-blog posts publish post_123 --expected-version 3You can use direct status updates instead:
cli-blog posts update post_123 --status published --expected-version 3 --jsonOr publish immediately on create:
cli-blog posts create \
--title "Launch notes" \
--body "Published immediately." \
--status published \
--jsonRead delivery content:
cli-blog posts list \
--status published \
--fields summary,seo \
--include authors,media \
--jsonUpload media:
cli-blog media upload ./cover.png --alt-text "Product screenshot" --caption "Launch dashboard" --jsonWork with localization, revisions, redirects, and XML helpers:
cli-blog locales list --json
cli-blog categories create --name "Noticias" --locale es-MX --slug noticias
cli-blog posts revisions list post_123 --json
cli-blog posts revisions get post_123 rev_123 --json
cli-blog posts redirects get old-launch-notes --locale en-US --json
cli-blog sitemap get --locale en-US > sitemap.xml
cli-blog feed get --locale en-US > feed.xmlUse demo mode across command families:
cli-blog posts create --demo --title "A developer's guide to San Francisco"
cli-blog authors create --demo --public-name "Maya Chen"
cli-blog media upload --demo --file ./bay-walk.png --alt-text "Morning light over San Francisco Bay"
cli-blog categories create --demo --name "San Francisco"
cli-blog tags create --demo --name "city-notes"
cli-blog feed get --demoErrors are written to stderr and failed commands exit non-zero. Destructive real API commands ask for confirmation unless --yes is passed.