zernio-cli
v0.8.0
Published
Unofficial agent-friendly CLI for the Zernio API
Maintainers
Readme
zernio-cli
Unofficial, agent-friendly CLI for the Zernio API. Schedule posts, manage inbox, broadcasts, sequences, and automations across 16 platforms from the terminal.
This package keeps the existing human workflow commands (posts:create, media:upload, inbox:*, etc.) and adds generated OpenAPI discovery plus a generic authenticated API caller for full API coverage.
Official Zernio SDK/docs remain the source of truth:
- API docs: https://docs.zernio.com/
- OpenAPI: docs/openapi/zernio-api-openapi.yaml
- Node SDK: https://github.com/zernio-dev/zernio-node
Install
npm install -g zernio-cliThe binary is zernio. A deprecated late alias remains for compatibility.
Auth
# Browser login for local interactive use
zernio auth:login
# API key for CI/headless use
zernio auth:set --key "sk_your-api-key"
# Or use env
export ZERNIO_API_KEY="sk_your-api-key"
# Verify without printing secrets
zernio doctor --connection --prettyConfig resolution:
- One-off flags where supported, such as
--api-keyand--base-url ZERNIO_API_KEY,ZERNIO_API_URL~/.zernio/config.json- Deprecated fallbacks:
LATE_*,~/.late/config.json
The published CLI does not auto-load .env from the current directory. For local repo testing, opt in explicitly:
ZERNIO_CLI_LOAD_ENV=1 zernio doctor --connection --pretty
ZERNIO_CLI_LOAD_ENV=1 ZERNIO_CLI_ENV_FILE=.env npm testCommon Workflows
# List profiles and accounts
zernio profiles:list --pretty
zernio accounts:list --pretty
# Upload media, then use returned public URL in a post
zernio media:upload ./photo.jpg --pretty
zernio posts:create \
--text "Launch update" \
--accounts <accountId1>,<accountId2> \
--media "https://public-url-from-upload" \
--scheduledAt "2026-06-20T09:00:00Z"
# Native X/Twitter quote, reply, and thread options
zernio posts:create \
--text "Thread display title" \
--accounts <twitterAccountId> \
--threadJson '["tweet 1","tweet 2"]'
zernio posts:create \
--text "my take" \
--accounts <twitterAccountId> \
--quoteTweetId "https://x.com/user/status/2061975910467698972"
# Content disclosure labels (X + Instagram)
zernio posts:create --text "sponsored" --accounts <xId> --paidPartnership --sensitiveMedia
zernio posts:create --text "generated with AI" --accounts <igId> --aiGenerated
# Generic passthrough for Reddit/TikTok/YouTube/Pinterest etc.
zernio posts:create \
--text "cross-platform post" \
--accounts <redditId>,<tiktokId> \
--platform-data '{"reddit":{"subreddit":"programming"},"tiktok":{"privacy":"PUBLIC"}}'
# Richer media (gif/document, altText, thumbnails) via --media-json
zernio posts:create \
--text "with rich media" \
--accounts <accountId> \
--media-json '[{"type":"gif","url":"https://cdn.example/a.gif","altText":"demo"}]'
# Queue scheduling (native flags)
zernio posts:create \
--text "Queued post" \
--accounts <accountId> \
--queuedFromProfile <profileId> \
--queueId <queueId>
# Recycling, crossposting, mentions, metadata
zernio posts:create \
--text "recycled" \
--accounts <accountId> \
--recycling '{"enabled":true,"interval":"weekly","intervalCount":1}' \
--crosspostingEnabled \
--mentions '["@brand"]' \
--metadata '{"source":"cli"}'Do not call queue/next-slot and feed that time back into scheduledFor; the docs define next-slot as preview-only.
Full API Coverage
The CLI generates a compact endpoint catalog from the bundled OpenAPI spec.
# Search endpoints
zernio api:catalog --tag Posts --search retry --pretty
# Inspect parameters/request body shape
zernio api:describe createPost --pretty
zernio api:describe "GET /v1/posts" --pretty
# Call any endpoint
zernio api:call getPost --path postId=post_123 --pretty
zernio api:call listPosts --query limit=10 --query page=1 --pretty
zernio api:call createPost --body-file ./post.json --dry-run --pretty
zernio api:call createPost --body-file ./post.json --request-id req_123 --pretty
zernio api:call listPinterestBoardsForSelection --header X-Connect-Token=conn_123 --pretty
zernio api:call uploadWhatsAppNumberKycDocument \
--header X-Filename=passport.pdf \
--content-type application/octet-stream \
--raw-body-file ./passport.pdfapi:call returns:
{
"ok": true,
"status": 200,
"statusText": "OK",
"rateLimit": {
"limit": "600",
"remaining": "599",
"reset": "1760000000",
"retryAfter": null
},
"data": {}
}For media uploads, prefer zernio media:upload; it implements the official presign + direct PUT workflow.
Reliability Rules
- JSON is default; use
--prettyfor readable JSON. - Branch automation on error
typeandcodewhen the API returns them, not message text. - Respect
Retry-AfterandX-RateLimit-*headers. - Use
--request-idor--idempotency-keyfor mutating calls that document safe retry headers. - Use pagination, caching, webhooks, and bulk endpoints for automation.
- Use
platformSpecificDatafor per-platform post settings.posts:createwraps common X/Twitter fields with--quoteTweetId,--replyToTweetId,--replySettings,--threadJson(alias:--threadItems),--threadFile,--paidPartnership,--sensitiveMedia, and--platformSpecificData; Instagram AI disclosure with--aiGenerated; and generic per-platform overrides via--platform-data '{"reddit":{...}}'. Use--media-jsonfor richer media items (gif/document/altText/title/thumbnails) — wins over--mediawhen both are set. - Flag precedence on
posts:create:--draftwins over scheduling; then--scheduledAt; then--queuedFromProfile(server assigns the next slot); otherwisepublishNowdefaults to true.--queueIdrequires--queuedFromProfile.--platform-data '{"twitter":{...}}'is applied after the X-specific helpers and shallow-overrides overlapping keys — the CLI warns to stderr and lists the overridden fields when you set both; use--platformSpecificDataif you want the X validators (quote/reply/thread conflicts) to see your custom fields.--sensitiveMedianeeds attached media (--mediaor--media-json); the CLI warns to stderr if you set it text-only. Media type is inferred from the URL extension (.gif→gif, video extensions →video, otherwiseimage), ignoring query strings and fragments; pass an explicittypein--media-jsonto override. - For failed
posts:createcalls, use--debug-safeto print non-secret account/platform diagnostics. - Check current platform support at https://docs.zernio.com/platforms instead of relying on a fixed count.
Development
npm ci
npm run generate:openapi
npm run build
npm test
npm run test:coverage
npm audit --omit=optional
# Optional live connection test using repo .env
ZERNIO_CLI_LOAD_ENV=1 node dist/index.js doctor --connection --prettyRelease policy:
main: stable npm/GitHub releasedev: beta prerelease- semantic-release generates versions and changelog from conventional commits
License
MIT
