CLI
Schedule posts from your terminal, shell scripts, cron jobs and CI pipelines. One command, the same rules as the app.
Install
Node.js 18 or newer. No other dependencies. Run it once with npx or install it globally:
npx postika --help
# or
npm install -g postika
postika --versionLog in
- 1In Postika, open your project → Connect AI (Conectar IA) → Project keys (Claves de proyecto) and create a key (
ptk_…). - 2Run
postika loginand paste it. The key is checked against the server and saved to~/.config/postika/config.json, readable only by you (0600).
postika login
postika whoamiIn CI, skip login and set the key as a secret environment variable instead. --api-key and --base-url work on every command too.
| Variable | Use |
|---|---|
| POSTIKA_API_KEY | API key. Takes priority over the saved one. |
| POSTIKA_BASE_URL | Server URL, for a self-hosted or test instance. Defaults to https://postika.app. |
| NO_COLOR | Plain output without colors. |
Commands
| Command | What it does |
|---|---|
| postika login | Save an API key |
| postika logout | Remove the saved key |
| postika whoami | Project, time zone, plan, role and warnings of the current key |
| postika projects | Projects the key can reach |
| postika channels | Connected channels with their IDs and limits |
| postika posts list | Posts of the next 14 days, a date range or a status |
| postika posts create | Schedule, publish now, send for approval or save a draft |
| postika posts get <id> | One post with the status, error and URL of each channel |
| postika posts delete <id> | Delete a post (asks for confirmation; --yes to skip) |
| postika posts approve <id> | Approve a post pending approval |
Add --json to any command to print the raw API response, ready for jq. Errors go to stderr with a non-zero exit code; with --json they are printed as JSON too.
Create a post
# Schedule (project local time)
postika posts create --text "We just shipped dark mode" --channels linkedin,x --at "2026-11-12 09:30"
# Photo from your disk, saved as a draft
postika posts create --text "Behind the scenes" --channels @mybrand --media ./photo.jpg --draft
# Every channel, pending approval, shorter text for X
postika posts create -t "Our autumn collection is live" -c all \
--text-for "x=Autumn drop is live 🍂" --at "2026-11-14 18:00" --approval
# Text from a file or another command
cat post.txt | postika posts create --text - --channels threads --now--text, -tstringrequired- Post text, 1 to 5000 characters.
-reads it from stdin. --channels, -clistrequired- Comma-separated channel IDs, handles (
@mybrand) or network names (linkedin,x,instagram…), orall. A handle matches every channel with that handle. --atstringYYYY-MM-DD HH:MMin the project's time zone. Required to schedule or send for approval.--media, -mfile | url- A local photo or video (uploaded with POST /api/v1/media) or a public
https://link. Repeat it or separate with commas, up to 10. --draftflag- Save as a draft (
--atoptional). --approvalflag- Leave it pending until an owner or admin approves it.
--nowflag- Publish right away.
--text-forstring- Different text for one channel:
"<channel>=<text>". Repeatable. --notestring- Note for whoever approves it. Not published.
Without --draft, --approval or --now, the post is scheduled for --at. The same checks as the app run first: character limits, required media, channels to reconnect and the plan.
List and inspect posts
postika posts list # next 14 days
postika posts list --from 2026-12-01 --to 2026-12-31 # up to 62 days
postika posts list --status failed # latest 100 failed posts
postika posts get f2b1c0de-5a4e-4d0b-8a77-0c6e3b9d1a42
postika posts delete f2b1c0de-5a4e-4d0b-8a77-0c6e3b9d1a42 --yesScripts and CI
GitHub Actions
Announce every release on your channels. Store the key as a repository secret.
on:
release:
types: [published]
jobs:
announce:
runs-on: ubuntu-latest
steps:
- run: |
npx -y postika posts create \
--text "${{ github.event.release.name }} is out: ${{ github.event.release.html_url }}" \
--channels linkedin,x --approval \
--at "$(TZ=Europe/Madrid date -d '+1 hour' '+%Y-%m-%d %H:%M')"
env:
POSTIKA_API_KEY: ${{ secrets.POSTIKA_API_KEY }}With jq
# IDs of every failed post
postika posts list --status failed --json | jq -r '.[].id'
# Channel ID of your LinkedIn page
postika channels --json | jq -r '.[] | select(.network == "LinkedIn") | .id'--base-url http://localhost:3000 or POSTIKA_BASE_URL. Errors and limits are the same as the REST API; see Errors & limits.