Skip to Content
CLI

CLI


Interface specification

This page is the interface specification for @voxburst/cli version 0.2.x (covers 0.2.0, 0.2.1, and 0.2.2).

Verified binary: @voxburst/cli@0.2.2 — npm latest, published 2026-05-20.

If you have 0.2.0 or 0.2.1 installed, this spec applies to your version without change — all flags, --json field names, exit codes, and --file schemas are identical across every 0.2.x release.

voxburst --version # confirm your version npm install -g @voxburst/cli@latest # upgrade to 0.2.2 if needed

Schema stability guarantee

JSON output fields: All field names, types, and enum values documented in this page are stable for the lifetime of 0.2.x. Scripts written against any 0.2.x release will continue to work without changes against any later 0.2.x release.

Additive changes only: New fields may be added to any --json output in a 0.2.x release. Removed or renamed fields signal a major version bump.

Flag compatibility guarantee

All flags documented in this page are stable for the lifetime of 0.2.x. Flag removal or rename requires a major version bump and a minimum 30-day deprecation notice.

Compatibility and deprecation policy

Change typeVersion signalNotice
New flag or JSON field0.2.x patchNone required — additive
New command0.2.x or 0.3.xNone required — additive
Flag rename or removal1.0.0 (major)30-day deprecation notice
JSON field rename or removal1.0.0 (major)30-day deprecation notice
Exit code behavior change1.0.0 (major)30-day deprecation notice
--file schema change (breaking)1.0.0 (major)30-day deprecation notice

Post to social media directly from your terminal, scripts, and CI pipelines.

npm install -g @voxburst/cli # global install npx @voxburst/cli --help # run without installing

The package name is @voxburst/cli but the command is voxburst. Do not run @voxburst/cli directly.


Automation contract (read this first)

Everything an operator needs to know before scripting against the CLI. Details are in the sections below; this is the canonical single-location summary.

Which commands are safe for scripting

Command--json--quietMutates stateSafe for CINotes
postYesCreates and publishes a post
scheduleYesCreates a scheduled post
validateNoNever mutates; always exits 0
posts listNoRead-only
posts getNoRead-only
posts deleteYes⚠️Destructive — use carefully
accounts listNoRead-only
accounts connectYesOpens browser — not headless
whoamiNoAuth check
statusNoRead-only overview
config set/get/listYes/No⚠️Mutates local config file
loginYes⚠️Use VOXBURST_API_KEY env var in CI instead
analyticsNoRead-only

Exit codes

CodeMeaning
0Command completed — does not guarantee all platforms published
1Infrastructure error (auth, network, bad args, rate limit, server error)

Exit 0 ≠ success for post/schedule. Always check results[].status per platform.
validate always exits 0 — content failing platform rules is not an error. Check .[].valid.

JSON shape stability

  • Fields documented in this page are stable for voxburst@0.2.x
  • New fields may appear in any minor release — write scripts defensively: jq '.field // empty'
  • Fields will not be removed or renamed without a major version bump
  • The CLI status set (draft, scheduled, published, failed) is a subset of the REST API — do not pass REST statuses to --status

Credential precedence

1. --api-key flag (where supported) 2. VOXBURST_API_KEY environment variable ← use this in CI 3. api-key in ~/.voxburst/config.json 4. (no key → exit 1)

Partial success

post and schedule exit 0 when the post record is created, even if platform publishing fails. Check results[].status in every automation script:

RESULT=$(voxburst post "Hello" -p twitter,instagram --json) FAILED=$(echo "$RESULT" | jq '[.results[] | select(.status=="failed")] | length') [ "$FAILED" -gt 0 ] && { echo "Platform failure" >&2; exit 1; }

Rate limits and retry

  • HTTP 429 → exit 1, message to stderr
  • CLI does not auto-retry
  • Implement backoff in the calling script (see CI workflow example)

Install and upgrade

npm install -g @voxburst/cli voxburst --help

If voxburst is not found after installing:

# zsh (macOS default) echo 'export PATH="$PATH:$(npm config get prefix)/bin"' >> ~/.zshrc && source ~/.zshrc # bash echo 'export PATH="$PATH:$(npm config get prefix)/bin"' >> ~/.bashrc && source ~/.bashrc

Upgrade:

npm install -g @voxburst/cli@latest voxburst --version

First-time operator workflow

Copy and paste this entire block. Every line is a real command.

# 1. Install npm install -g @voxburst/cli # 2. Set API key (get it from app.voxburst.io/settings/api) voxburst login --api-key vb_live_xxxxxxxxxxxxx # 3. Verify auth voxburst whoami # 4. List connected accounts — copy an account ID for the next step voxburst accounts list --json # 5. Validate content against your target platform before posting voxburst validate "Hello from VoxBurst!" -p twitter --json # 6. Post (replace acc_twitter_abc with your account ID from step 4) voxburst post "Hello from VoxBurst!" -p twitter --json # 7. Inspect the result — check .status and .results[].status voxburst posts list --status published --json | head -40

If step 3 fails with 401, regenerate your API key and repeat step 2.
If step 4 shows no accounts, run voxburst accounts connect twitter first.


Authentication

The CLI supports two authentication methods. API key auth is recommended for scripts, automation, and CI/CD. Cognito (email/password) is for interactive sessions.

voxburst login --api-key vb_live_xxxxxxxxxxxxx # Stored in ~/.voxburst/config.json (permissions: 0600)

Or via environment variable (takes precedence over config file):

export VOXBURST_API_KEY=vb_live_xxxxxxxxxxxxx voxburst whoami

Credential precedence order:

  1. VOXBURST_API_KEY environment variable
  2. api-key in ~/.voxburst/config.json

Cognito (email/password)

voxburst login --email you@example.com # Prompts for password interactively voxburst login --email you@example.com --password yourpass

Cognito login stores a session token in ~/.voxburst/config.json. Tokens expire; re-run voxburst login if you receive 401 errors.

Verify auth

voxburst whoami

Credential storage and security

  • Config file: ~/.voxburst/config.json
  • File permissions: 0600 (owner read/write only)
  • Config directory: ~/.voxburst/ (permissions: 0700)
  • The API key is stored in plaintext at 0600 — treat it like a password

Rotate credentials:

voxburst config set api-key vb_live_new_key_here # Or unset entirely: voxburst config delete api-key

Config and environment variables

Config file reference

Stored at ~/.voxburst/config.json. Manage via voxburst config.

KeyCLI flagDescriptionDefault
api-keyvoxburst config set api-key <value>API key for authentication
api-urlvoxburst config set api-url <value>API base URL overridehttps://api.voxburst.io
default-platformsvoxburst config set default-platforms twitter,linkedinPlatforms used when -p is omittedtwitter
voxburst config set api-key vb_live_xxxxxxxxxxxxx voxburst config set default-platforms twitter,linkedin,instagram voxburst config get api-key voxburst config list # show all config voxburst config delete api-key # remove a value

Environment variables

VariableOverridesDescription
VOXBURST_API_KEYapi-key in configAPI key (takes precedence over config file)
VOXBURST_API_URLapi-url in configAPI base URL override

Environment variables always override config file values.


Exit codes

All CLI commands exit with a consistent code:

Exit codeMeaning
0Success
1Any error (auth failure, validation failure, network error, platform failure, config error, bad arguments)

The CLI does not currently distinguish between error categories by exit code. Use --json and parse the error field in scripts that need to distinguish failure types.

voxburst post "Hello" && echo "success" || echo "failed (exit $?)"

JSON output schemas

Add --json to any command to get machine-readable output on stdout. Error output always goes to stderr regardless of --json.

Contract guarantee (voxburst@0.2.2): Every field in the tables below is present in the shipped binary. Fields will not be removed or renamed without a major version bump. New fields may be added in any release — write scripts defensively (jq '.field // empty'). Verify against your installed version with voxburst --version.

voxburst whoami --json

Success (exit 0):

{ "id": "usr_abc123", "email": "you@example.com", "name": "Your Name", "plan": "pro", "createdAt": "2026-01-01T00:00:00Z" }
FieldTypeNullableValues
idstringnocuid2 ID
emailstringno
namestringyes
planstringnofree pro team enterprise
createdAtstringnoISO 8601 UTC

Failure (exit 1, stderr): Error: VoxBurst API Error (401): Invalid API key


voxburst accounts list --json

Success (exit 0):

{ "data": [ { "id": "acc_twitter_abc", "platform": "twitter", "username": "mybrand", "displayName": "My Brand", "status": "active", "connectedAt": "2026-03-01T10:00:00Z" } ] }
FieldTypeNullableValues
dataarraynoArray of account objects
data[].idstringnoAccount ID — use this in -p and --file
data[].platformstringnotwitter linkedin instagram facebook threads bluesky mastodon youtube
data[].usernamestringnoPlatform handle
data[].displayNamestringyesDisplay name
data[].statusstringnoactive expired disconnected
data[].connectedAtstringnoISO 8601 UTC

Failure (exit 1, stderr): Error: VoxBurst API Error (401): Invalid API key


voxburst post "..." --json and voxburst schedule "..." --json

Success — published (exit 0):

{ "id": "post_abc123", "content": "Hello!", "platforms": ["twitter"], "status": "published", "scheduledAt": null, "publishedAt": "2026-03-15T10:00:05Z", "createdAt": "2026-03-15T10:00:00Z", "results": [{ "platform": "twitter", "accountId": "acc_twitter_abc", "status": "success", "postUrl": "https://x.com/mybrand/status/123" }] }

Success — scheduled (exit 0):

{ "id": "post_abc123", "content": "Hello!", "platforms": ["twitter"], "status": "scheduled", "scheduledAt": "2026-06-01T15:00:00Z", "publishedAt": null, "createdAt": "2026-03-15T10:00:00Z", "results": [] }

Platform failure — CLI exits 0, check results[].status (exit 0):

{ "id": "post_abc123", "content": "Hello!", "platforms": ["twitter"], "status": "failed", "scheduledAt": null, "publishedAt": null, "createdAt": "2026-03-15T10:00:00Z", "results": [{ "platform": "twitter", "accountId": "acc_twitter_abc", "status": "failed", "error": "Content exceeds Twitter character limit", "postUrl": null }] }

Partial success: The CLI exits 0 even when platform publishing fails. Always check results[].status — the top-level status field reflects the post record state, not publication success. A post can have status: "published" with individual platform results showing "failed".

FieldTypeNullableValues
idstringnoPost ID
contentstringno
platformsstring[]noPlatform names
statusstringnodraft scheduled published failed (complete list for CLI 0.2.2)
scheduledAtstringyesISO 8601 UTC or null
publishedAtstringyesISO 8601 UTC or null
createdAtstringnoISO 8601 UTC
resultsarraynoEmpty for drafts/scheduled; per-platform publish results once attempted
results[].platformstringnoPlatform name
results[].accountIdstringnoAccount ID
results[].statusstringnosuccess failed
results[].postUrlstringyesLive URL if published, null if failed
results[].errorstringyesError message if failed, null if succeeded

voxburst posts list --json

Success (exit 0): Array of post objects (same shape as post/schedule above, without results).

[ { "id": "post_abc123", "content": "Hello world", "platforms": ["twitter"], "status": "scheduled", "scheduledAt": "2026-06-01T15:00:00Z", "createdAt": "2026-05-30T10:00:00Z" }, { "id": "post_def456", "content": "Second post", "platforms": ["linkedin"], "status": "draft", "scheduledAt": null, "createdAt": "2026-05-29T09:00:00Z" } ]

Empty result (exit 0): []


voxburst posts get <id> --json

Same shape as post --json above including results.

Not found (exit 1, stderr): Error: Post not found


voxburst validate "..." --json

All valid (exit 0):

[{ "valid": true, "platform": "twitter", "errors": [], "warnings": [] }]

Validation failure (exit 0 — validation ran; check valid field per platform):

[ { "valid": false, "platform": "instagram", "errors": [{ "code": "MEDIA_REQUIRED", "message": "Instagram requires at least one image or video", "field": "media" }], "warnings": [] }, { "valid": true, "platform": "twitter", "errors": [], "warnings": [{ "code": "NO_HASHTAGS", "message": "Posts with hashtags typically get more reach on Twitter", "suggestion": "Consider adding 1-2 relevant hashtags" }] } ]

validate always exits 0. Validation itself is not an error — it ran successfully. Check .[].valid to determine if content passes platform rules. Only infrastructure errors (auth, network) cause exit 1.

FieldTypeNullableValues
Array rootarraynoOne object per platform validated
[].validbooleannotrue if no errors
[].platformstringnoPlatform name
[].errorsarraynoEmpty if valid
[].errors[].codestringnoMachine-readable error code
[].errors[].messagestringnoHuman-readable message
[].errors[].fieldstringyesWhich field caused the error
[].warningsarraynoNon-blocking issues
[].warnings[].codestringno
[].warnings[].messagestringno
[].warnings[].suggestionstringyes

voxburst status --json

{ "user": { "id": "usr_abc", "email": "you@example.com", "plan": "pro" }, "accounts": { "data": [ ...account objects... ] }, "recentPosts": [ ...post objects... ] }

Formal JSON Schemas

Machine-readable JSON Schema (draft-07) for every --json output and the --file input. Use these to write validation, wrappers, and tests against the CLI without ambiguity.

voxburst whoami --json

{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["id", "email", "plan", "createdAt"], "properties": { "id": { "type": "string" }, "email": { "type": "string", "format": "email" }, "name": { "type": ["string", "null"] }, "plan": { "type": "string", "enum": ["free", "pro", "team", "enterprise"] }, "createdAt": { "type": "string", "format": "date-time" } } }

voxburst accounts list --json

{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["data"], "properties": { "data": { "type": "array", "items": { "type": "object", "required": ["id", "platform", "username", "status", "connectedAt"], "properties": { "id": { "type": "string" }, "platform": { "type": "string", "enum": ["twitter","linkedin","instagram","facebook","threads","bluesky","mastodon","youtube","tiktok","pinterest","reddit","snapchat","telegram","google_business","whatsapp"] }, "username": { "type": "string" }, "displayName": { "type": ["string", "null"] }, "status": { "type": "string", "enum": ["active", "expired", "disconnected"] }, "connectedAt": { "type": "string", "format": "date-time" } } } } } }

voxburst post --json / voxburst schedule --json

{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["id", "content", "platforms", "status", "createdAt", "results"], "properties": { "id": { "type": "string" }, "content": { "type": "string" }, "platforms": { "type": "array", "items": { "type": "string" } }, "status": { "type": "string", "enum": ["draft", "scheduled", "published", "failed"] }, "scheduledAt": { "type": ["string", "null"], "format": "date-time" }, "publishedAt": { "type": ["string", "null"], "format": "date-time" }, "createdAt": { "type": "string", "format": "date-time" }, "results": { "type": "array", "items": { "type": "object", "required": ["platform", "accountId", "status"], "properties": { "platform": { "type": "string" }, "accountId": { "type": "string" }, "status": { "type": "string", "enum": ["success", "failed"] }, "postUrl": { "type": ["string", "null"] }, "error": { "type": ["string", "null"] } } } } } }

voxburst posts list --json

Array of post objects. Each item matches the post --json schema above minus the results field.

voxburst validate --json

{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "required": ["valid", "platform", "errors", "warnings"], "properties": { "valid": { "type": "boolean" }, "platform": { "type": "string" }, "errors": { "type": "array", "items": { "type": "object", "required": ["code", "message"], "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "field": { "type": ["string", "null"] } } } }, "warnings": { "type": "array", "items": { "type": "object", "required": ["code", "message"], "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "suggestion": { "type": ["string", "null"] } } } } } } }

--file input schema

{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["content"], "properties": { "content": { "type": "string", "minLength": 1 }, "platforms": { "type": "array", "items": { "type": "string" } }, "scheduledAt": { "type": "string", "format": "date-time", "description": "Always use UTC (Z suffix) in files" }, "media": { "type": "array", "items": { "type": "object", "required": ["path"], "properties": { "path": { "type": "string" }, "altText": { "type": ["string", "null"] } } } } }, "additionalProperties": false }

additionalProperties: false — unrecognised fields cause a parse error in 0.2.2.


Scheduling and timezone semantics

The CLI accepts datetimes in two formats:

FormatExampleBehavior
ISO 8601 with timezone2026-06-01T15:00:00ZUTC — recommended
ISO 8601 with offset2026-06-01T11:00:00-04:00Offset preserved
ISO 8601 without timezone2026-06-01T15:00:00Interpreted in local system timezone
Space-separated2026-06-01 15:00Interpreted in local system timezone

Timezone gotcha: If you omit the timezone offset (e.g. 2026-06-01T15:00:00), the time is interpreted in the timezone of the machine running the CLI. This is correct for interactive use but can cause bugs in CI/CD — a GitHub Actions runner is UTC, a developer laptop may be UTC-5.

Always use explicit UTC (Z) in scripts and CI:

voxburst schedule "..." --at "2026-06-01T15:00:00Z"

Examples — always append Z in scripts:

# ✅ UTC — safe in any environment voxburst schedule "Launch post" --at "2026-06-01T15:00:00Z" -p twitter # ✅ Offset — explicit, portable voxburst schedule "Launch post" --at "2026-06-01T11:00:00-04:00" -p twitter # ⚠️ No timezone — interpreted in local TZ; avoid in scripts voxburst schedule "Launch post" --at "2026-06-01T15:00:00" -p twitter # Validate a schedule time without committing voxburst schedule "Test" --at "2026-06-01T15:00:00Z" --draft # creates a draft; inspect, then delete

File input schema (--file)

The --file flag accepts a JSON file. This is the exact schema — any unrecognised field is silently ignored.

Field contract

FieldTypeRequiredDescription
contentstringYesPost text
platformsstring[]NoLowercase platform names. Falls back to default-platforms config if omitted.
scheduledAtstringNoISO 8601 datetime. Always use UTC (Z suffix) in files to avoid system-timezone bugs.
mediaobject[]NoLocal media files to upload
media[].pathstringYes (if media present)Absolute or relative path to image/video
media[].altTextstringNoAccessibility alt text

Example 1 — minimal (post now)

{ "content": "Hello from a file!" }

Example 2 — scheduled post

{ "content": "Weekly roundup — five things we shipped this week.", "platforms": ["twitter", "linkedin"], "scheduledAt": "2026-06-06T17:00:00Z" }

Always use UTC in files. "scheduledAt": "2026-06-06T17:00:00" (no Z) is parsed in the local timezone of the machine that runs voxburst post --file. A cron job on a UTC server and a developer on UTC-5 will schedule for different times. Add Z to be explicit.

Example 3 — media-rich post with alt text

{ "content": "Behind the scenes of our product launch 📸", "platforms": ["instagram", "twitter"], "scheduledAt": "2026-06-01T15:00:00Z", "media": [ { "path": "/home/user/images/launch-hero.jpg", "altText": "Team celebrating the product launch" }, { "path": "/home/user/images/launch-dashboard.jpg", "altText": "Screenshot of the new dashboard" } ] }
voxburst post --file post.json voxburst post --file post.json --json # get full JSON response

Account connection and OAuth

List connected accounts

voxburst accounts list voxburst accounts list --json # machine-readable voxburst accounts list -q # IDs only, one per line

Connect a new account

voxburst accounts connect twitter

This opens a browser window for OAuth authorization. Complete the OAuth flow in the browser, then return to the terminal — the account will be confirmed as connected.

Platform-specific preconditions:

  • Instagram: Must connect through Facebook; requires Business or Creator account
  • LinkedIn: Approve all requested permissions including w_member_social
  • Facebook: After connecting, select a Page via voxburst accounts list and note the account ID
  • YouTube: Approve youtube.upload and youtube.readonly scopes
  • Bluesky: Uses app passwords, not OAuth — see voxburst login with Bluesky-specific flow
  • Mastodon: Provide your instance URL when prompted

Headless / non-interactive: accounts connect always opens a browser — it cannot be run headlessly. For CI: connect accounts interactively first on a developer machine, confirm status: active with accounts list --json, then use the resulting account IDs in automation. Account IDs do not change after reconnection.

What happens step by step:

  1. CLI opens your default browser to the VoxBurst OAuth page
  2. You authorize the connection in the browser
  3. VoxBurst redirects to a localhost callback URL
  4. CLI receives the callback, stores the token, and prints confirmation

If the browser does not open: Copy the URL printed to your terminal and open it manually.

Disconnect an account

voxburst accounts disconnect <account-id>

Reconnect an expired account

When voxburst accounts list --json shows "status": "expired", the OAuth token can no longer be refreshed silently. Any post attempt to that account will fail.

# Identify expired accounts voxburst accounts list --json | jq '.data[] | select(.status == "expired") | {id, platform, username}' # Reconnect voxburst accounts connect twitter # opens browser; completes the full OAuth flow again # Confirm voxburst accounts list --json | jq '.data[] | select(.platform == "twitter") | .status' # Should print: "active"

Account IDs are stable across reconnection — your existing scripts using the account ID do not need to be updated after reconnecting an expired account.


Command reference

voxburst post

Create and publish a post immediately.

voxburst post "Hello world!" voxburst post "Hello!" -p twitter,linkedin voxburst post "Hello!" -p instagram -m /path/to/image.jpg voxburst post --file post.json voxburst post "Draft" --draft voxburst post "Hello!" --json
FlagDescription
[content]Post text (positional argument, or omit with --file)
-p, --platforms <list>Comma-separated platforms. Default: default-platforms config
-m, --media <paths>Comma-separated media file paths
-f, --file <path>Read post from JSON file (see file schema)
-d, --draftSave as draft instead of publishing
--jsonOutput result as JSON
-q, --quietMinimal output (post ID only)

Instagram requires at least one media file (-m) on every post. A text-only post to Instagram will fail.


voxburst schedule

Schedule a post for a future time. Shorthand for post --schedule.

voxburst schedule "Launch day!" --at "2026-06-01T15:00:00Z" voxburst schedule "Launch day!" --at "2026-06-01T15:00:00Z" -p twitter,linkedin voxburst schedule "Launch day!" --at "2026-06-01 15:00" -p twitter # local timezone voxburst schedule "Launch day!" --at "2026-06-01T15:00:00Z" --json
FlagDescription
<content>Post text (required positional)
--at <datetime>Required. When to publish. See scheduling semantics.
-p, --platforms <list>Comma-separated platforms
-m, --media <paths>Comma-separated media file paths
--jsonOutput result as JSON
-q, --quietMinimal output

voxburst validate

Check content against platform rules without creating a post.

voxburst validate "My post content" voxburst validate "My post content" -p twitter,instagram voxburst validate "My post content" --json

Returns per-platform valid, errors, and warnings. See JSON output.


voxburst posts

Manage existing posts.

voxburst posts list voxburst posts list --status scheduled voxburst posts list --status draft --json voxburst posts get post_abc123 voxburst posts get post_abc123 --json voxburst posts delete post_abc123

posts list flags:

FlagDescription
-s, --status <status>Filter by status. Accepted values (complete list): draft, scheduled, published, failed
-l, --limit <n>Number of posts to return (default: 20)
--offset <n>Pagination offset (default: 0). CLI uses offset-based pagination, not cursor.
--jsonOutput as JSON array
-q, --quietPost IDs only, one per line

voxburst accounts

voxburst accounts list voxburst accounts list --json voxburst accounts list -q # IDs only voxburst accounts connect twitter voxburst accounts disconnect acc_twitter_abc

voxburst analytics

voxburst analytics post post_abc123 voxburst analytics account acc_twitter_abc voxburst analytics post post_abc123 --json

voxburst status

Show workspace overview: authenticated user, connected accounts, recent posts.

voxburst status voxburst status --json

voxburst whoami

Show the authenticated user and active workspace.

voxburst whoami voxburst whoami --json

voxburst config

Manage CLI configuration.

voxburst config set api-key vb_live_xxxxxxxxxxxxx voxburst config set default-platforms twitter,linkedin voxburst config get api-key voxburst config list voxburst config delete api-key

voxburst webhooks

voxburst webhooks list voxburst webhooks create --url https://example.com/hook --events post.published voxburst webhooks delete hook_abc123

voxburst login

voxburst login --api-key vb_live_xxxxxxxxxxxxx voxburst login --email you@example.com # prompts for password voxburst login --email you@example.com --password pass # non-interactive

Platform capability matrix (CLI)

Platform names in the CLI are lowercase (twitter, instagram, etc.).

PlatformCLI nameMedia requiredFirst commentSchedulingNotes
Twitter / XtwitterNo✗ (via REST)Max 280 chars
LinkedInlinkedinNo✗ (via REST)Max 3,000 chars
InstagraminstagramYes✗ (via REST)Media always required; Business/Creator only
FacebookfacebookNo✗ (via REST)Pages only
ThreadsthreadsNoRequires Instagram account
YouTubeyoutubeYes (video)✗ (via REST)Video-only; 6 uploads/day
BlueskyblueskyNoMax 300 graphemes
MastodonmastodonNoLimit varies by instance

First comments via CLI are not currently supported. Use the REST API (firstComment field on POST /v1/posts) for first-comment workflows in scripts.


Automation and CI/CD

Shell script

#!/bin/bash set -euo pipefail # Set via environment — never hardcode export VOXBURST_API_KEY="${VOXBURST_API_KEY}" # Validate before posting if ! voxburst validate "$CONTENT" -p twitter --json | jq -e '.[0].valid' > /dev/null 2>&1; then echo "Validation failed" >&2 exit 1 fi # Post and capture ID POST_ID=$(voxburst post "$CONTENT" -p twitter -q) echo "Posted: $POST_ID"

Cron job

# Post every Monday at 9 AM UTC 0 9 * * 1 VOXBURST_API_KEY=vb_live_xxx /usr/local/bin/voxburst post --file /etc/voxburst/monday-post.json >> /var/log/voxburst.log 2>&1

GitHub Actions

- name: Post to social media env: VOXBURST_API_KEY: ${{ secrets.VOXBURST_API_KEY }} run: | # Always use UTC timestamps in CI npx @voxburst/cli schedule "Weekly update" \ --at "$(date -u -d '+1 hour' '+%Y-%m-%dT%H:%M:%SZ')" \ -p twitter,linkedin \ --json

Parse JSON output in scripts

# Check if post succeeded RESULT=$(voxburst post "Hello" -p twitter --json) STATUS=$(echo "$RESULT" | jq -r '.status') if [ "$STATUS" = "published" ]; then URL=$(echo "$RESULT" | jq -r '.results[0].postUrl') echo "Published: $URL" else echo "Post failed with status: $STATUS" >&2 exit 1 fi

Retry on failure

The CLI exits 1 on any failure but does not retry automatically. Implement retry in the calling script:

for i in 1 2 3; do voxburst post "$CONTENT" -p twitter && break echo "Attempt $i failed — retrying in 30s..." >&2 sleep 30 done

CI workflow example

A complete, copy-pasteable CI script with set -e, --json, per-platform failure checking, and retry logic:

#!/bin/bash # voxburst-post.sh — canonical CI posting script set -euo pipefail CONTENT="${POST_CONTENT:-}" PLATFORMS="${POST_PLATFORMS:-twitter,linkedin}" SCHEDULE_AT="${POST_SCHEDULE_AT:-}" # ISO 8601 UTC, or empty to post now MAX_RETRIES=3 if [ -z "$CONTENT" ]; then echo "ERROR: POST_CONTENT is required" >&2 exit 1 fi if [ -z "${VOXBURST_API_KEY:-}" ]; then echo "ERROR: VOXBURST_API_KEY is not set" >&2 exit 1 fi # Validate before posting — exit 1 if any platform fails validation VALIDATION=$(voxburst validate "$CONTENT" -p "$PLATFORMS" --json) INVALID=$(echo "$VALIDATION" | jq '[.[] | select(.valid == false)] | length') if [ "$INVALID" -gt 0 ]; then echo "ERROR: Content failed validation:" >&2 echo "$VALIDATION" | jq '[.[] | select(.valid == false)]' >&2 exit 1 fi # Post with retry for attempt in $(seq 1 $MAX_RETRIES); do if [ -n "$SCHEDULE_AT" ]; then RESULT=$(voxburst schedule "$CONTENT" --at "$SCHEDULE_AT" -p "$PLATFORMS" --json) && break else RESULT=$(voxburst post "$CONTENT" -p "$PLATFORMS" --json) && break fi if [ "$attempt" -lt "$MAX_RETRIES" ]; then echo "Attempt $attempt failed — retrying in 30s..." >&2 sleep 30 else echo "ERROR: All $MAX_RETRIES attempts failed" >&2 exit 1 fi done # Check per-platform results (CLI exits 0 even on platform failure) FAILED=$(echo "$RESULT" | jq '[.results[] | select(.status == "failed")] | length') if [ "$FAILED" -gt 0 ]; then echo "WARNING: $FAILED platform(s) failed to publish:" >&2 echo "$RESULT" | jq '[.results[] | select(.status == "failed") | {platform, error}]' >&2 exit 1 fi # Report success POST_ID=$(echo "$RESULT" | jq -r '.id') echo "SUCCESS: Post $POST_ID published" echo "$RESULT" | jq '.results[] | {platform, postUrl}'

Usage in GitHub Actions:

- name: Post weekly update env: VOXBURST_API_KEY: ${{ secrets.VOXBURST_API_KEY }} POST_CONTENT: "Weekly update — five things we shipped." POST_PLATFORMS: "twitter,linkedin" POST_SCHEDULE_AT: "2026-06-06T17:00:00Z" run: bash ./scripts/voxburst-post.sh

CI security

  • Store VOXBURST_API_KEY as a CI secret — never in code or logs
  • Use --quiet or --json to avoid key echoing in verbose output
  • Pin a version in CI for reproducibility: npx @voxburst/cli@0.2.2

Error catalog and troubleshooting

All errors exit with code 1. Error messages go to stderr; --json does not suppress errors to stderr.

ErrorCauseFix
VOXBURST_API_KEY environment variable is requiredNo API key configuredvoxburst login --api-key vb_live_xxx or set VOXBURST_API_KEY
401 UnauthorizedAPI key invalid or expiredGenerate a new key at app.voxburst.io/settings/api
No accounts connectedNo social accounts linkedvoxburst accounts connect twitter
Platform not connected: instagramTarget platform not linkedvoxburst accounts connect instagram
Invalid datetime format--at value not parseableUse ISO 8601: --at "2026-06-01T15:00:00Z"
Schedule time must be in the future--at is in the pastCheck timezone — naive times use local TZ
File not found: post.json--file path wrongUse absolute path or check working directory
Content is requiredNo content and no --fileAdd content argument or --file flag
429 Rate limit exceededToo many requestsWait and retry; CLI does not auto-retry
Instagram requires mediaPosting text-only to InstagramAdd -m /path/to/image.jpg
Media file not found-m path invalidCheck the file path
Account expiredOAuth token expiredvoxburst accounts connect <platform> to reconnect

Debug mode:

voxburst debug # prints config state and auth status without making API calls

Quick recipes

Validate then publish

voxburst validate "My post content" -p twitter,instagram --json \ | jq -e 'map(select(.valid == false)) | length == 0' \ && voxburst post "My post content" -p twitter,instagram

Schedule a post from a file

cat > tonight.json << 'EOF' { "content": "Weekly roundup — five things we shipped this week.", "platforms": ["twitter", "linkedin"], "scheduledAt": "2026-06-06T17:00:00Z" } EOF voxburst post --file tonight.json --json

Fetch recent scheduled posts

voxburst posts list --status scheduled --json | jq '.[] | {id, scheduledAt, content: .content[:60]}'

Delete all draft posts

voxburst posts list --status draft -q | while read id; do voxburst posts delete "$id" && echo "Deleted $id" done

Cross-post to multiple platforms

voxburst post "Announcing our new feature! 🚀" \ -p twitter,linkedin,threads \ --json | jq '.results[] | {platform, status, postUrl}'

Security guidance

  • Shell history: Avoid passing API keys as inline arguments. Use voxburst login or VOXBURST_API_KEY env var instead of --api-key in interactive shells to prevent key leakage in ~/.bash_history or ~/.zsh_history.
  • CI secrets: Never print VOXBURST_API_KEY in CI logs. Use your CI platform’s masked secrets feature.
  • Config file permissions: ~/.voxburst/config.json is created with 0600 (owner read/write only). Do not change these permissions.
  • Shared machines: On shared servers, prefer environment variables over config files — other users cannot read your environment.
  • Key rotation: When rotating, set the new key first (voxburst config set api-key <new>), then revoke the old key in VoxBurst Settings.

Automation contract

This section defines the complete behavioral contract for scripting against the CLI.

Exit codes

CodeMeaningNotes
0Command succeededFor post/schedule: the post was created. Does not mean all platforms published. Check results[].status.
0validate ran (even if content invalid)Content failing platform rules is not an error — it ran. Check .[].valid.
1Any infrastructure errorAuth failure, network error, bad arguments, file not found, rate limit, server error

The CLI does not use exit codes to distinguish error categories. Parse --json output and stderr message to identify the error type in scripts.

Partial success

The CLI exits 0 when a post is created, even if one or more platforms fail to publish. Example:

RESULT=$(voxburst post "Hello" -p twitter,instagram -m /img.jpg --json) # Exit code: 0 # Check each platform individually: echo "$RESULT" | jq '.results[] | select(.status == "failed") | {platform, error}' # { "platform": "instagram", "error": "Aspect ratio invalid" }

Always check results[].status in automation — never assume exit 0 means all platforms published.

Rate limits

  • HTTP 429 responses cause exit code 1 with a message to stderr: VoxBurst API Error (429): Rate limit exceeded
  • The CLI does not auto-retry rate limits
  • Implement retry/backoff in the calling script (see CI workflow example)

JSON stability contract

  • Fields listed in the schema tables above are stable for voxburst@0.2.x
  • New fields may be added in any 0.2.x release — defensive scripting: jq '.field // empty'
  • Fields will not be removed or renamed without a major version bump and 30-day deprecation notice

--json vs --quiet in scripts

  • --json: full response object on stdout; errors on stderr
  • --quiet / -q: IDs only on stdout (one per line); use for piping to xargs or while read
  • Never mix --json and --quiet — they are mutually exclusive in intent

Versioning and compatibility

Version table

CLI versionnpm tagDocs verifiedKnown doc/binary gaps
0.2.2latestThis pageNone known
0.1.xdeprecated
voxburst --version # confirm installed version

Compatibility guarantees

--json output: Stable field names and types for fields documented in this page. Additive changes (new fields) may occur in any 0.2.x release.

Command flags: Flags documented here are stable in 0.x. Removals or renames bump the major version.

Doc-to-binary parity: Status values, flag names, and JSON fields are verified against voxburst@0.2.2. The CLI exposes a subset of the REST API — REST statuses (partial, approved, publishing, etc.) are not valid --status filter values.

Upgrade:

npm install -g @voxburst/cli@latest voxburst --version

OS-specific notes

macOS (zsh):

  • Quotes in shell: use "double quotes" for content with spaces or emoji
  • PATH setup: see install notes if voxburst is not found

Linux (bash):

  • Same as macOS; ensure Node.js 18+ is installed
  • In cron: always use absolute paths (/usr/local/bin/voxburst) and set env vars explicitly

Windows (PowerShell):

$env:VOXBURST_API_KEY = "vb_live_xxxxxxxxxxxxx" npx @voxburst/cli post "Hello from PowerShell!"

Use npx @voxburst/cli rather than voxburst directly on Windows unless you have the npm global bin in your PATH.


CLI contract changelog

Breaking changes (flag removals, JSON field removals, exit-code behavior changes) are listed here with the CLI version they were introduced in.

VersionReleasedChange typeDescription
0.2.22026-05-20Current npm latestInternal fixes; no interface changes from 0.2.1
0.2.12026-05-20FixInternal fixes; no interface changes from 0.2.0
0.2.0BaselineInitial 0.2.x interface — all docs in this page apply to 0.2.0+
0.1.xDeprecatedRemoved; flags from 0.1.x are no longer documented

Interface compatibility across 0.2.x: Flags, JSON field names, exit codes, and --file schema are identical across 0.2.0, 0.2.1, and 0.2.2. These docs are the specification for all three versions.

How to read this changelog:

  • Breaking — requires changes to existing scripts
  • Fix — previous behavior was incorrect; scripts relying on the old behavior should update
  • Additive — new flag or JSON field added; existing scripts unaffected
  • Deprecated — feature will be removed in the next major version

Subscribe to @voxburst/cli on npm (npm info @voxburst/cli dist-tags) to monitor releases.

Last updated on