Skip to content

wahlu/cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wahlu CLI

Manage your social media from the terminal. Works for humans, AI agents, and CI/CD pipelines.

Install

npm install -g @wahlu/cli

Authentication

Generate an API key at wahlu.com under Settings > API Keys.

# Option 1: Save to config
wahlu auth login wahlu_live_abc123...

# Option 2: Environment variable
export WAHLU_API_KEY=wahlu_live_abc123...

Authentication priority:

  1. WAHLU_API_KEY environment variable (highest)
  2. Saved key in ~/.config/wahlu/config.json

Quick start

# List your brands
wahlu brand list

# Set a default brand so you don't need --brand every time
wahlu brand switch <brand-id>

# List content items (via post alias)
wahlu post list

# Create a content item
wahlu post create --name "Monday motivation" \
  --copy-mode single \
  --single-copy '{"caption":"Rise and grind","hashtags":[]}' \
  --instagram '{"post_type":"GRID_POST"}'

# Schedule it
wahlu schedule create <content-item-id> \
  --at 2026-03-15T14:00:00Z \
  --integrations <integration-id>

# Upload media
wahlu media upload ./photo.jpg

# List what's been published
wahlu publication list

Commands

Auth

Command Description
wahlu auth login <key> Save API key to ~/.config/wahlu/config.json
wahlu auth logout Remove saved API key
wahlu auth status Show current auth method, masked key, and config

Brands

Brands represent social media profiles. All content items, media, publish runs, and queues belong to a brand.

Command Description
wahlu brand list List all brands
wahlu brand get <id> Get full brand details
wahlu brand switch <id> Set default brand for all commands

Response fields:

Field Type Description
id string Brand ID
name string Brand name
description string|null Brand description
logo_url string|null Logo URL
timezone string|null IANA timezone (e.g. Australia/Sydney)
website string|null Brand website URL
business_category string|null Business category
brand_kit object|null Brand kit (fonts, colours, voice)
content_preferences object|null CTA, logo frequency settings
image_posting object|null Image posting preferences
video_posting object|null Video posting preferences
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Content items (post command)

Content items are the core content unit. Captions/hashtags are canonical via copy_mode + single_copy/platform_copy, while platform settings control media/post options.

Command Description
wahlu post list List content items (paginated)
wahlu post get <id> Get full content item details
wahlu post create [options] Create a new content item
wahlu post update <id> [options] Update a content item (partial update)
wahlu post delete <id> Permanently delete a content item

Create/update options:

Option Description
--name <name> Content item name (max 500 chars)
--copy-mode <mode> Canonical caption mode: single or per_platform
--single-copy <json> Canonical shared copy JSON: {"caption":"...","hashtags":["..."],"title":"..."}
--platform-copy <json> Canonical per-platform copy JSON map
--instagram <json> Instagram settings as JSON string
--tiktok <json> TikTok settings as JSON string
--facebook <json> Facebook settings as JSON string
--youtube <json> YouTube settings as JSON string
--linkedin <json> LinkedIn settings as JSON string
--labels <ids...> Label IDs to attach (max 50)

Response fields:

Field Type Description
id string Content item ID
name string|null Content item name
brand_id string Brand ID
label_ids string[] Attached label IDs
created_by string|null Creator user ID
thumbnail_timestamp number Thumbnail timestamp (seconds)
copy_mode string|null single | per_platform
single_copy object|null Canonical shared caption + hashtags
platform_copy object|null Canonical per-platform caption map
instagram_settings object|null Instagram configuration
tiktok_settings object|null TikTok configuration
facebook_settings object|null Facebook configuration
youtube_settings object|null YouTube configuration
linkedin_settings object|null LinkedIn configuration
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Platform settings reference

Captions and hashtags come from canonical copy fields:

  • --copy-mode single --single-copy '{"caption":"...","hashtags":["..."]}'
  • --copy-mode per_platform --platform-copy '{"instagram":{"caption":"...","hashtags":[]}}'

Instagram (--instagram):

Field Type Values
post_type string GRID_POST | REEL | STORY
media_ids string[] Media IDs to attach
trial_reel boolean Post as trial reel (non-followers first)
graduation_strategy string MANUAL | SS_PERFORMANCE

TikTok (--tiktok):

Field Type Values
post_type string VIDEO | IMAGE | CAROUSEL
media_ids string[] Media IDs to attach
privacy_level string PUBLIC_TO_EVERYONE | MUTUAL_FOLLOW_FRIENDS | FOLLOWER_OF_CREATOR | SELF_ONLY
allow_comment boolean Allow comments (default: true)
allow_duet boolean Allow duets (default: true, video only)
allow_stitch boolean Allow stitches (default: true, video only)
auto_add_music boolean Auto-add music (photo/carousel only)
is_aigc boolean Disclose as AI-generated content
is_commercial_content boolean Mark as commercial/branded content

Facebook (--facebook):

Field Type Values
post_type string FB_POST | FB_STORY | FB_REEL | FB_TEXT
media_ids string[] Media IDs to attach

YouTube (--youtube):

Field Type Values
title string Video title
description string Video description
post_type string YT_SHORT | YT_VIDEO
media_ids string[] Media IDs to attach
privacy_level string PUBLIC | UNLISTED | PRIVATE
notify_subscribers boolean Notify subscribers on publish

LinkedIn (--linkedin):

Field Type Values
post_type string LI_TEXT | LI_IMAGE | LI_VIDEO | LI_ARTICLE
media_ids string[] Media IDs to attach
visibility string PUBLIC | CONNECTIONS
title string Article title (LI_ARTICLE only)
original_url string Article URL (LI_ARTICLE only)

Examples:

# Instagram grid post
wahlu post create --name "Photo post" \
  --copy-mode single \
  --single-copy '{"caption":"Hello!","hashtags":[]}' \
  --instagram '{"post_type":"GRID_POST","media_ids":["mid-123"]}'

# Cross-platform video
wahlu post create --name "Video" \
  --copy-mode per_platform \
  --platform-copy '{"tiktok":{"caption":"Check this out","hashtags":["video"]},"instagram":{"caption":"Check this out","hashtags":[]}}' \
  --tiktok '{"post_type":"VIDEO","media_ids":["mid-123"]}' \
  --instagram '{"post_type":"REEL","media_ids":["mid-123"]}'

# LinkedIn article
wahlu post create --name "Article share" \
  --copy-mode single \
  --single-copy '{"caption":"Read our latest","hashtags":[]}' \
  --linkedin '{"post_type":"LI_ARTICLE","original_url":"https://example.com","title":"Our Post"}'

Publish runs (schedule command)

Schedule content items for future publishing to specific integrations.

Command Description
wahlu schedule list List publish runs (paginated)
wahlu schedule create <content-item-id> Schedule a content item
wahlu schedule update <publish-run-id> Update a publish run (reschedule/retarget)
wahlu schedule delete <id> Remove a publish run (does not delete the content item)

Create options:

Option Required Description
--at <datetime> Yes ISO 8601 datetime (e.g. 2026-03-15T14:00:00Z)
--integrations <ids...> Yes Integration IDs to publish to (max 20)

Response fields:

Field Type Description
id string Publish run ID
content_item_id string Referenced content item ID
scheduled_at string ISO 8601 datetime
integration_ids string[] Integration IDs
status string e.g. ready_for_processing, published, failed
approval_status string|null Approval status
source string|null api for API-created entries
failure_reason string|null Failure reason
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Example:

wahlu schedule create content-abc \
  --at 2026-03-15T14:00:00Z \
  --integrations int-123 int-456

Queues

Queues define recurring time slots for automatic publishing.

Command Description
wahlu queue list List all queues
wahlu queue add <queue-id> <content-item-id> Append a content item to a queue

Response fields:

Field Type Description
id string Queue ID
name string Queue name
active boolean Whether the queue is active
mode string Queue mode
times_of_day string[] Scheduled times (e.g. ["09:00","17:00"])
timezone string|null IANA timezone
next_run_at string|null Next scheduled publishing time
loop boolean Whether to loop through posts
content_item_ids string[] Ordered content item IDs in the queue
integration_ids string[] Integration IDs
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Media

Upload images and videos to your media library.

Command Description
wahlu media list List media files (paginated)
wahlu media upload <file> Upload a local file
wahlu media delete <id> Permanently delete a media file

Supported formats: .png, .jpg, .jpeg, .gif, .webp, .mp4, .mov, .webm

Response fields:

Field Type Description
id string Media ID (use in media_ids arrays)
file_name string Original filename
content_type string MIME type (e.g. image/jpeg)
size number File size in bytes
duration number|null Duration in seconds (video only)
status string ready_for_processing | processing | completed | failed
download_url string|null Signed download URL
thumbnail_large_url string|null Large thumbnail
thumbnail_small_url string|null Small thumbnail
source string|null upload | generated | stock | scan
description string|null Media description
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Upload workflow:

# Upload returns a media ID
wahlu media upload ./photo.jpg
# Uploaded photo.jpg — media ID: mid-abc123

# Use the media ID in a content item
wahlu post create --name "Photo post" \
  --copy-mode single \
  --single-copy '{"caption":"Nice!","hashtags":[]}' \
  --instagram '{"post_type":"GRID_POST","media_ids":["mid-abc123"]}'

Ideas

Save content ideas for later development into full content items.

Command Description
wahlu idea list List ideas (paginated)
wahlu idea create <name> Save a new idea
wahlu idea delete <id> Delete an idea

Create options:

Option Description
--description <text> Detailed description (max 10000 chars)
--type <type> Idea type (max 50 chars)

Response fields:

Field Type Description
id string Idea ID
name string|null Idea name/title
description string|null Detailed description
type string|null Idea type
status string Status
labels string[] Text labels
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Labels

Labels categorise and organise content items and media.

Command Description
wahlu label list List all labels
wahlu label create <name> Create a label
wahlu label delete <id> Delete a label

Create options:

Option Description
--color <hex> Colour hex code (e.g. #ff5500)

Response fields:

Field Type Description
id string Label ID
name string Label name
color string|null Colour hex code
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Integrations (read-only)

Connected social media accounts. You need integration IDs when scheduling content items.

Command Description
wahlu integration list List connected integrations

Response fields:

Field Type Description
id string Integration ID (use in --integrations when scheduling)
platform string instagram | tiktok | facebook | youtube | linkedin
status string Connection status
display_name string|null Display name on the platform
username string|null Platform username/handle
avatar_url string|null Profile avatar URL
permissions object|null Granted permissions
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Publications (read-only)

Records of content items published to social media platforms.

Command Description
wahlu publication list List published content items (paginated)

Response fields:

Field Type Description
id string Publication ID
platform string instagram | tiktok | facebook | youtube | linkedin
post_id string Source content item ID
post_name string|null Content item name
post_type string|null Post type
status string processing | published | failed
source string|null calendar (from schedule) or queue (from queue)
failure_reason string|null Failure reason
integration_id string Integration used
publish_id string|null Platform content ID
published_at string When published (ISO 8601)
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

Global options

Flag Description
--brand <id> Use a specific brand (overrides default)
--json Output as JSON (available on all list/get/create/update commands)
--help Show help for any command
--version Show CLI version

Pagination

All list commands support pagination:

Flag Default Max Description
--page <n> 1 - Page number
--limit <n> 50 100 Items per page

Configuration

Config is stored at ~/.config/wahlu/config.json:

{
  "api_key": "wahlu_live_...",
  "api_url": "https://api.wahlu.com",
  "default_brand_id": "abc123"
}

Environment variables take priority over config file:

Variable Description
WAHLU_API_KEY API key
WAHLU_API_URL API base URL (default: https://api.wahlu.com)
WAHLU_BRAND_ID Default brand ID

For AI agents

Every command supports --json for structured output:

# Get content item IDs
wahlu post list --json | jq '.[].id'

# Get integration IDs for scheduling
wahlu integration list --json | jq '.[] | {id, platform, username}'

# Find failed publications
wahlu publication list --json | jq '.[] | select(.status == "failed")'

# Create and capture the ID
CONTENT_ITEM_ID=$(wahlu post create --name "Auto post" --json | jq -r '.id')
wahlu schedule create $CONTENT_ITEM_ID --at 2026-03-15T14:00:00Z --integrations int-123

Documentation

Full documentation: wahlu.com/docs

License

MIT

About

Wahlu CLI — manage your social media from the terminal

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors