CLI
Interface specification
This page is the interface specification for
@voxburst/cliversion0.3.x(currently0.3.0), and also covers0.2.0–0.2.2where noted.Verified binary:
@voxburst/cli@0.3.0— npmlatest.If you have
0.2.xinstalled, every flag,--jsonfield name, exit code, and--fileschema on this page still applies unchanged —0.3.0is additive only (new top-level commandsdebugandcompletion, and newposts create/posts update/posts cancelsubcommands). Nothing documented for0.2.xwas renamed or removed.voxburst --version # confirm your version npm install -g @voxburst/cli@latest # upgrade to 0.3.0 if needed
Schema stability guarantee
JSON output fields: All field names, types, and enum values documented in this page are stable across 0.2.x and 0.3.x. Scripts written against any 0.2.x or 0.3.x release will continue to work without changes against any later release in that range.
Additive changes only: New fields may be added to any --json output in a 0.2.x/0.3.x release. Removed or renamed fields signal a major version bump.
Flag compatibility guarantee
All flags documented in this page are stable across 0.2.x and 0.3.x. Flag removal or rename requires a major version bump and a minimum 30-day deprecation notice.
Compatibility and deprecation policy
| Change type | Version signal | Notice |
|---|---|---|
| New flag or JSON field | 0.2.x patch | None required — additive |
| New command | 0.2.x or 0.3.x | None required — additive |
| Flag rename or removal | 1.0.0 (major) | 30-day deprecation notice |
| JSON field rename or removal | 1.0.0 (major) | 30-day deprecation notice |
| Exit code behavior change | 1.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 installingThe 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 | --quiet | Mutates state | Safe for CI | Notes |
|---|---|---|---|---|---|
post | ✅ | ✅ | Yes | ✅ | Creates and publishes a post |
schedule | ✅ | ✅ | Yes | ✅ | Creates a scheduled post |
validate | ✅ | ✗ | No | ✅ | Never mutates; always exits 0 |
posts list | ✅ | ✅ | No | ✅ | Read-only |
posts get | ✅ | ✗ | No | ✅ | Read-only |
posts delete | ✗ | ✅ | Yes | ⚠️ | Destructive — use carefully |
accounts list | ✅ | ✅ | No | ✅ | Read-only |
accounts connect | ✗ | ✗ | Yes | ❌ | Opens browser — not headless |
whoami | ✅ | ✗ | No | ✅ | Auth check |
status | ✅ | ✗ | No | ✅ | Read-only overview |
config set/get/list | ✗ | ✗ | Yes/No | ⚠️ | Mutates local config file |
login | ✗ | ✗ | Yes | ⚠️ | Use VOXBURST_API_KEY env var in CI instead |
analytics | ✅ | ✗ | No | ✅ | Read-only |
Exit codes
| Code | Meaning |
|---|---|
0 | Command completed — does not guarantee all platforms published |
1 | Infrastructure 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-0.3.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
Global install
npm install -g @voxburst/cli
voxburst --helpIf 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 ~/.bashrcUpgrade:
npm install -g @voxburst/cli@latest
voxburst --versionFirst-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 -40If 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.
API key (recommended)
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 whoamiCredential precedence order:
VOXBURST_API_KEYenvironment variableapi-keyin~/.voxburst/config.json
Cognito (email/password)
voxburst login --email you@example.com
# Prompts for password interactively
voxburst login --email you@example.com --password yourpassCognito login stores a session token in ~/.voxburst/config.json. Tokens expire; re-run voxburst login if you receive 401 errors.
Verify auth
voxburst whoamiCredential 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-keyConfig and environment variables
Config file reference
Stored at ~/.voxburst/config.json. Manage via voxburst config.
| Key | CLI flag | Description | Default |
|---|---|---|---|
api-key | voxburst config set api-key <value> | API key for authentication | — |
api-url | voxburst config set api-url <value> | API base URL override | https://api.voxburst.io |
default-platforms | voxburst config set default-platforms twitter,linkedin | Platforms used when -p is omitted | twitter |
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 valueEnvironment variables
| Variable | Overrides | Description |
|---|---|---|
VOXBURST_API_KEY | api-key in config | API key (takes precedence over config file) |
VOXBURST_API_URL | api-url in config | API base URL override |
Environment variables always override config file values.
Exit codes
All CLI commands exit with a consistent code:
| Exit code | Meaning |
|---|---|
0 | Success |
1 | Any 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.3.0): 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" }| Field | Type | Nullable | Values |
|---|---|---|---|
id | string | no | cuid2 ID |
email | string | no | |
name | string | yes | |
plan | string | no | free pro team enterprise |
createdAt | string | no | ISO 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" }
]
}| Field | Type | Nullable | Values |
|---|---|---|---|
data | array | no | Array of account objects |
data[].id | string | no | Account ID — use this in -p and --file |
data[].platform | string | no | twitter linkedin instagram facebook threads bluesky mastodon youtube |
data[].username | string | no | Platform handle |
data[].displayName | string | yes | Display name |
data[].status | string | no | active expired disconnected |
data[].connectedAt | string | no | ISO 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".
| Field | Type | Nullable | Values |
|---|---|---|---|
id | string | no | Post ID |
content | string | no | |
platforms | string[] | no | Platform names |
status | string | no | draft scheduled published failed (complete list for CLI 0.3.0 — unchanged since 0.2.0) |
scheduledAt | string | yes | ISO 8601 UTC or null |
publishedAt | string | yes | ISO 8601 UTC or null |
createdAt | string | no | ISO 8601 UTC |
results | array | no | Empty for drafts/scheduled; per-platform publish results once attempted |
results[].platform | string | no | Platform name |
results[].accountId | string | no | Account ID |
results[].status | string | no | success failed |
results[].postUrl | string | yes | Live URL if published, null if failed |
results[].error | string | yes | Error 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.
| Field | Type | Nullable | Values |
|---|---|---|---|
| Array root | array | no | One object per platform validated |
[].valid | boolean | no | true if no errors |
[].platform | string | no | Platform name |
[].errors | array | no | Empty if valid |
[].errors[].code | string | no | Machine-readable error code |
[].errors[].message | string | no | Human-readable message |
[].errors[].field | string | yes | Which field caused the error |
[].warnings | array | no | Non-blocking issues |
[].warnings[].code | string | no | |
[].warnings[].message | string | no | |
[].warnings[].suggestion | string | yes |
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.3.0 (and every 0.2.x release).
Scheduling and timezone semantics
The CLI accepts datetimes in two formats:
| Format | Example | Behavior |
|---|---|---|
| ISO 8601 with timezone | 2026-06-01T15:00:00Z | UTC — recommended |
| ISO 8601 with offset | 2026-06-01T11:00:00-04:00 | Offset preserved |
| ISO 8601 without timezone | 2026-06-01T15:00:00 | Interpreted in local system timezone |
| Space-separated | 2026-06-01 15:00 | Interpreted 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 deleteFile input schema (--file)
The --file flag accepts a JSON file. This is the exact schema — any unrecognised field is silently ignored.
Field contract
| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Post text |
platforms | string[] | No | Lowercase platform names. Falls back to default-platforms config if omitted. |
scheduledAt | string | No | ISO 8601 datetime. Always use UTC (Z suffix) in files to avoid system-timezone bugs. |
media | object[] | No | Local media files to upload |
media[].path | string | Yes (if media present) | Absolute or relative path to image/video |
media[].altText | string | No | Accessibility 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 responseAccount connection and OAuth
List connected accounts
voxburst accounts list
voxburst accounts list --json # machine-readable
voxburst accounts list -q # IDs only, one per lineConnect a new account
voxburst accounts connect twitterThis 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 listand note the account ID - YouTube: Approve
youtube.uploadandyoutube.readonlyscopes - Bluesky: Uses app passwords, not OAuth — see
voxburst loginwith 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:
- CLI opens your default browser to the VoxBurst OAuth page
- You authorize the connection in the browser
- VoxBurst redirects to a localhost callback URL
- 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| Flag | Description |
|---|---|
[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, --draft | Save as draft instead of publishing |
--json | Output result as JSON |
-q, --quiet | Minimal 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| Flag | Description |
|---|---|
<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 |
--json | Output result as JSON |
-q, --quiet | Minimal 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" --jsonReturns 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_abc123posts list flags:
| Flag | Description |
|---|---|
-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. |
--json | Output as JSON array |
-q, --quiet | Post IDs only, one per line |
posts create (0.3.0+): equivalent to top-level voxburst post, nested under posts for scripts that prefer subcommand grouping.
voxburst posts create "Hello world!" -p twitter,linkedin
voxburst posts create "Draft copy" --draft| Flag | Description |
|---|---|
<content> | Post text (required positional) |
-p, --platforms <list> | Comma-separated platforms |
-s, --schedule <datetime> | Schedule for later (ISO 8601 or "YYYY-MM-DD HH:mm") |
-d, --draft | Save as draft instead of publishing immediately |
--json | Output as JSON |
-q, --quiet | Minimal output |
posts update <id> [content] (0.3.0+): update an existing post’s content, schedule, or platforms.
voxburst posts update post_abc123 "Updated copy"
voxburst posts update post_abc123 -s "2026-09-01T15:00:00Z"| Flag | Description |
|---|---|
<id> | Post ID (required positional) |
[content] | New post text (optional — omit to leave content unchanged) |
-s, --schedule <datetime> | New scheduled time (ISO 8601 or "YYYY-MM-DD HH:mm") |
-p, --platforms <list> | Comma-separated platforms |
--json | Output as JSON |
posts cancel <id> (0.3.0+): cancel a scheduled post.
voxburst posts cancel post_abc123
voxburst posts cancel post_abc123 --force # skip confirmation prompt| Flag | Description |
|---|---|
<id> | Post ID (required positional) |
-f, --force | Skip the confirmation prompt |
--json | Output as JSON |
-q, --quiet | Minimal output |
posts validate <content> (0.3.0+): identical to top-level voxburst validate, nested under posts.
voxburst accounts
voxburst accounts list
voxburst accounts list --json
voxburst accounts list -q # IDs only
voxburst accounts connect twitter
voxburst accounts disconnect acc_twitter_abcvoxburst analytics
voxburst analytics post post_abc123
voxburst analytics account acc_twitter_abc
voxburst analytics post post_abc123 --jsonvoxburst status
Show workspace overview: authenticated user, connected accounts, recent posts.
voxburst status
voxburst status --jsonvoxburst whoami
Show the authenticated user and active workspace.
voxburst whoami
voxburst whoami --jsonvoxburst 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-keyvoxburst webhooks
voxburst webhooks list
voxburst webhooks create --url https://example.com/hook --events post.published
voxburst webhooks delete hook_abc123voxburst 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-interactivevoxburst debug (0.3.0+)
Debug tools for troubleshooting the CLI itself — not part of the automation contract; treat as a manual/interactive aid, not a scriptable command.
voxburst debug config # print resolved config + auth status
voxburst debug request GET /accounts # make a raw authenticated API request
voxburst debug request POST /posts '{"content":"test"}'| Subcommand | Description |
|---|---|
debug config | Show current configuration (API key source, base URL, workspace) without making API calls |
debug request <method> <path> [body] | Make a raw API request through the CLI’s configured auth and base URL. --json is the default output format. |
voxburst completion (0.3.0+)
Generates a shell completion script. See Shell completion below for setup and its static-list caveat.
voxburst completion --shell bash
voxburst completion --shell zsh # defaultPlatform capability matrix (CLI)
Platform names in the CLI are lowercase (twitter, instagram, etc.).
| Platform | CLI name | Media required | First comment | Scheduling | Notes |
|---|---|---|---|---|---|
| Twitter / X | twitter | No | ✗ (via REST) | ✅ | Max 280 chars |
linkedin | No | ✗ (via REST) | ✅ | Max 3,000 chars | |
instagram | Yes | ✗ (via REST) | ✅ | Media always required; Business/Creator only | |
facebook | No | ✗ (via REST) | ✅ | Pages only | |
| Threads | threads | No | ✗ | ✅ | Requires Instagram account |
| YouTube | youtube | Yes (video) | ✗ (via REST) | ✅ | Video-only; 6 uploads/day |
| Bluesky | bluesky | No | ✗ | ✅ | Max 300 graphemes |
| Mastodon | mastodon | No | ✗ | ✅ | Limit 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>&1GitHub 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 \
--jsonParse 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
fiRetry 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
doneCI 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.shCI security
- Store
VOXBURST_API_KEYas a CI secret — never in code or logs - Use
--quietor--jsonto avoid key echoing in verbose output - Pin a version in CI for reproducibility:
npx @voxburst/cli@0.3.0
Error catalog and troubleshooting
All errors exit with code 1. Error messages go to stderr; --json does not suppress errors to stderr.
| Error | Cause | Fix |
|---|---|---|
VOXBURST_API_KEY environment variable is required | No API key configured | voxburst login --api-key vb_live_xxx or set VOXBURST_API_KEY |
401 Unauthorized | API key invalid or expired | Generate a new key at app.voxburst.io/settings/api |
No accounts connected | No social accounts linked | voxburst accounts connect twitter |
Platform not connected: instagram | Target platform not linked | voxburst accounts connect instagram |
Invalid datetime format | --at value not parseable | Use ISO 8601: --at "2026-06-01T15:00:00Z" |
Schedule time must be in the future | --at is in the past | Check timezone — naive times use local TZ |
File not found: post.json | --file path wrong | Use absolute path or check working directory |
Content is required | No content and no --file | Add content argument or --file flag |
429 Rate limit exceeded | Too many requests | Wait and retry; CLI does not auto-retry |
Instagram requires media | Posting text-only to Instagram | Add -m /path/to/image.jpg |
Media file not found | -m path invalid | Check the file path |
Account expired | OAuth token expired | voxburst accounts connect <platform> to reconnect |
Debug mode:
voxburst debug config # prints config state and auth status without making API callsQuick 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,instagramSchedule 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 --jsonFetch 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"
doneCross-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 loginorVOXBURST_API_KEYenv var instead of--api-keyin interactive shells to prevent key leakage in~/.bash_historyor~/.zsh_history. - CI secrets: Never print
VOXBURST_API_KEYin CI logs. Use your CI platform’s masked secrets feature. - Config file permissions:
~/.voxburst/config.jsonis created with0600(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
| Code | Meaning | Notes |
|---|---|---|
0 | Command succeeded | For post/schedule: the post was created. Does not mean all platforms published. Check results[].status. |
0 | validate ran (even if content invalid) | Content failing platform rules is not an error — it ran. Check .[].valid. |
1 | Any infrastructure error | Auth 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
1with 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)
Shell completion
voxburst completion
Generates a shell completion script. Completion covers top-level commands and the
subcommands of accounts and posts.
| Flag | Values | Default | Description |
|---|---|---|---|
--shell | bash, zsh | Auto-detected from $SHELL | Which shell to emit a script for |
Enable it by evaluating the output from your shell startup file:
# bash — add to ~/.bashrc
eval "$(voxburst completion --shell bash)"
# zsh — add to ~/.zshrc
eval "$(voxburst completion --shell zsh)"To inspect the generated script without installing it:
voxburst completion --shell bashThe completion script is generated from a static command list compiled into the
binary. Re-run the eval line (or restart your shell) after upgrading the CLI so
completions reflect any newly added commands.
JSON stability contract
- Fields listed in the schema tables above are stable for
voxburst@0.2.x-0.3.x - New fields may be added in any
0.2.x/0.3.xrelease — 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 toxargsorwhile read- Never mix
--jsonand--quiet— they are mutually exclusive in intent
Versioning and compatibility
Version table
| CLI version | npm tag | Docs verified | Known doc/binary gaps |
|---|---|---|---|
0.3.0 | latest | This page | mock-oauth is not documented — see note below |
0.2.x | superseded | This page (unchanged) | Same gap as 0.3.0 |
0.1.x | deprecated | — | — |
The binary also exposes a mock-oauth command that is intentionally not
documented here. It is a local development aid, not part of the supported CLI
contract, and its behaviour may change or be removed without a version bump. Do
not use it in scripts or CI.
voxburst --version # confirm installed versionCompatibility 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/0.3.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.3.0. 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 --versionOS-specific notes
macOS (zsh):
- Quotes in shell: use
"double quotes"for content with spaces or emoji - PATH setup: see install notes if
voxburstis 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.
| Version | Released | Change type | Description |
|---|---|---|---|
0.3.0 | 2026-08-26 | Current npm latest | Additive — adds top-level debug and completion commands, and posts create/posts update/posts cancel subcommands. No interface changes to anything documented for 0.2.x. |
0.2.2 | 2026-05-20 | Fix | Internal fixes; no interface changes from 0.2.1 |
0.2.1 | 2026-05-20 | Fix | Internal fixes; no interface changes from 0.2.0 |
0.2.0 | — | Baseline | Initial 0.2.x interface — all docs in this page apply to 0.2.0+ |
0.1.x | — | Deprecated | Removed; flags from 0.1.x are no longer documented |
Interface compatibility across 0.2.x–0.3.0: Flags, JSON field names, exit codes, and --file schema are identical across 0.2.0, 0.2.1, 0.2.2, and 0.3.0. These docs are the specification for all four versions.
How to read this changelog:
Breaking— requires changes to existing scriptsFix— previous behavior was incorrect; scripts relying on the old behavior should updateAdditive— new flag or JSON field added; existing scripts unaffectedDeprecated— feature will be removed in the next major version
Subscribe to @voxburst/cli on npm (npm info @voxburst/cli dist-tags) to monitor releases.