CLI
Run posterly from your terminal: authenticate, schedule posts, upload media, and automate workflows with @posterly/cli.
The posterly CLI (@posterly/cli on npm) gives you terminal access to the same public API that powers the REST API and MCP integrations. Use it for scripts, CI jobs, support playbooks, local debugging, and AI coding agents that can run shell commands.
Quick start
No install needed:
npx -y @posterly/cli@latest auth:login
npx -y @posterly/cli@latest doctor --pretty
npx -y @posterly/cli@latest accounts:list --pretty
Or install globally for a permanent posterly command:
npm i -g @posterly/cli@latest
posterly doctor --pretty
Requirements
- Node.js 20 or newer
- A posterly account with the API add-on ($3/month on any plan)
- An API key from Dashboard -> Settings -> API Keys, or browser login via
auth:login
Authentication
Pick whichever fits your environment:
posterly auth:login: opens your browser for OAuth (PKCE). Best for humans on their own machine.posterly auth:key: paste an API key into a hidden prompt. It is stored in~/.posterly/config.jsonwith restrictive permissions.POSTERLY_API_KEYenvironment variable: best for CI, scripts, and agents. Nothing is written to disk.
Check your setup any time:
posterly doctor --pretty
Doctor verifies your Node version, the API origin, that a key is configured, that the key works against /api/v1/whoami, and whether a newer CLI version is published. It exits nonzero if anything fails, so you can use it as a CI preflight step.
Output is JSON by default
Every command prints JSON to stdout, so output pipes cleanly into jq, CI logs, or agent tooling. Add --pretty when a human is reading.
posterly posts:list --status scheduled | jq '.posts[].caption'
Command reference
| Area | Commands |
|---|---|
| Auth | auth:login, auth:key, auth:status, auth:logout |
| Health | doctor, version, whoami |
| Accounts | accounts:list, accounts:disconnect, connect:link |
| Brands | brands:list, brands:get, brands:accounts, brands:profile |
| Platforms | platforms:list, platforms:schema, platforms:trigger |
| Posts | posts:list, posts:get, posts:create, posts:update, posts:status, posts:missing, posts:release-id, posts:delete, posts:delete-group, posts:batch |
| Scheduling | slots:next |
| Media | media:upload, media:signed-upload, media:upload-from-url |
| Analytics | analytics:account, analytics:posts |
| Google Business | gbp:reviews, gbp:review-link, gbp:audit, gbp:media, gbp:add-media, gbp:delete-media, gbp:suggest-reply, gbp:reply, gbp:delete-reply |
| AI | ai:captions, ai:image, ai:video-options, ai:video-function, ai:generate-video, ai:video-jobs, ai:video-job |
| Operations | activity:list, notifications:list, x:quota |
| Webhooks | webhooks:list, webhooks:create, webhooks:update, webhooks:delete, webhooks:test |
| OAuth clients | oauth:clients, oauth:create-client, oauth:update-client, oauth:delete-client |
Run posterly help for flags, or see the API reference for full request and response details; every command maps 1:1 to a /api/v1 route.
Common workflows
Schedule a post:
posterly posts:create \
--account-id <account-id> \
--caption "Launching soon" \
--scheduled-at 2026-07-10T09:00:00Z
Find open posting slots, then schedule into one:
posterly slots:next --count 3 --timezone America/New_York --pretty
Generate AI captions before drafting:
posterly ai:captions --platforms instagram,linkedin --brief "Announcing our summer sale" --tone playful --count 3 --pretty
Generate an AI image for a post:
posterly ai:image "A minimal flat-lay of a desk with coffee" --aspect-ratio 1:1 --style photographic --pretty
Upload media and use it in a post:
posterly media:upload ./photo.jpg
posterly posts:create --account-id <account-id> --caption "New drop" --media-url <returned-url>
Catch and inspect failures:
posterly posts:list --status failed --pretty
posterly posts:missing <post-id> --pretty
Safety guardrails
- Destructive commands (
posts:delete,posts:delete-group,accounts:disconnect,webhooks:delete,gbp:reply,gbp:add-media,gbp:delete-media, and others) refuse to run without an explicit--confirmflag. - The CLI refuses to send API keys to non-local
http://origins. - AI commands that spend credits (
ai:image,ai:generate-video) call cost-guarded endpoints; useai:video-function estimate_costto preview video costs first. - Keys are read from a hidden prompt or environment variable so they stay out of shell history.
Using the CLI with AI agents
The CLI is the easiest way to give a terminal-capable coding agent (Claude Code, OpenClaw, Cursor, and similar) full posterly access: JSON output, no MCP configuration, and built-in confirmation gates on destructive actions.
Claude Code plugin (recommended for Claude Code)
Install the official plugin so Claude Code gets the posterly skill, bundled MCP server, and guided setup:
/plugin marketplace add awpthorp/posterly-agent
/plugin install posterly@posterly-agent
Then set your API key in the plugin userConfig (or export POSTERLY_API_KEY) and run npx -y @posterly/cli@latest doctor --pretty. See Claude Code plugin for the full walkthrough.
Skills CLI (any skill-compatible agent)
Install the posterly agent skill, which teaches agents the CLI, MCP, and REST interfaces together:
npx skills add awpthorp/posterly-agent
Then set POSTERLY_API_KEY in the agent's environment. See the agents overview and MCP setup for the MCP-based alternative.
CI usage
# GitHub Actions example
- name: Schedule release post
env:
POSTERLY_API_KEY: ${{ secrets.POSTERLY_API_KEY }}
run: |
npx -y @posterly/cli@latest doctor --no-npm
npx -y @posterly/cli@latest posts:create \
--account-id "$ACCOUNT_ID" \
--caption "v2.0 is live" \
--scheduled-at "$PUBLISH_AT"
Rate limits and scopes match the REST API: see API documentation for details.