$ postctl

The missing CLI for social posting — YouTube, Instagram, Facebook, X, LinkedIn.
Built for humans and AI agents. Zero dependencies. Auditable by design.

official OAuth APIs no daemon · no database JSON out for pipes MIT

Install

curl (standalone binary)

curl -fsSL https://post-ctl.pages.dev/install.sh | sh

npm / npx

npm i -g post-ctl       # package post-ctl · command postctl

bun

bunx post-ctl --version

macOS & Linux (arm64/x64) prebuilt. Windows via npm.

Quickstart

1 — guided setup (one sitting)

postctl setup youtube

Walks you through the Google Cloud project, consent screen, and OAuth client, then logs you in and verifies your channel. Re-runnable and resumable.

2 — pre-flight (offline, free)

postctl validate "My talk" --media ./talk.mp4 --account isha

3 — post

postctl post "My talk" --media ./talk.mp4 \
  --description ./notes.txt --tags "wisdom,talk" --account isha

Agent & script integration

Everything speaks JSON when stdout isn't a TTY (or with --output json), and the exit code is the contract — no output parsing needed to branch.

Exit codes

CodeMeaning
0success
1validation / API failure
4auth required — run auth login

bash

# dry-run first; only post if the payload validates
if postctl validate "$TITLE" --media "$FILE" --account isha; then
  postctl post "$TITLE" --media "$FILE" --account isha --output json > result.json
else
  echo "invalid, skipping" >&2
fi

health check in a pipeline

# exit 1 if any account/token/staging check fails
postctl doctor --output json | jq -e '.[] | select(.status=="fail")' && exit 1 || true

cron (daily scheduled post)

# 09:00 daily — tokens refresh silently; no interaction in the write path
0 9 * * *  /usr/bin/env postctl post "$(cat /srv/today.txt)" \
             --media /srv/clip.mp4 --account isha --output json \
             >> /var/log/postctl.log 2>&1