↓ メインコンテンツへスキップ
0

Buffer CLI Playbook #

Procedures, command workflows, and safety gates for scheduling social media posts, managing channels, and automating publication workflows via the Buffer CLI (@bufferapp/cli).


Architecture & Progressive Disclosure #

To minimize context consumption, SKILL.md contains core operational commands, critical pitfalls, and safety rules directly in the body. Load specialized references on demand:

  • Automation Workflows: Read references/workflows.md for shell scripting patterns, timezone math, and Relay cursor pagination.
  • Rate Limits & Idempotency: Read references/rate_limits.md for 429 backoff algorithms, retry matrices, and duplicate-post prevention.

1. Bootstrapping & Installation #

The Buffer CLI is generated from Buffer’s public GraphQL schema, returning structured JSON with predictable error handling.

Agent Bootstrap Sequence #

When running in a new environment or container, follow this self-bootstrapping sequence:

bash
# 1. Check if the Buffer CLI is already installed
if ! command -v buffer &> /dev/null; then
  echo "Buffer CLI not found. Installing globally via npm (requires Node.js 18+)..."
  npm install -g @bufferapp/cli
fi

# 2. Verify installation version
buffer --version

# 3. Diagnose environment, config, API token, and network reachability
buffer doctor
💡 TIP

In ephemeral sandbox environments where global npm installation is restricted, you can invoke the CLI on the fly using npx:

bash
npx -y @bufferapp/cli doctor

Authentication Modes #

  1. Environment Variable (Recommended for CI / Ephemeral Agents):
    bash
    export BUFFER_API_KEY="your-api-key"
  2. Global Configuration (buffer init):
    bash
    buffer init
    Writes API token, default organization, and timezone to $XDG_CONFIG_HOME/buffer/config.json (or ~/.config/buffer/config.json).

2. Core Operational Workflows #

❗ IMPORTANT

Always use --output json when invoking commands within automated scripts or agent subshells to ensure clean machine parsing.

Workflow A: Channel Discovery & Account Inspection #

Always inspect available channels before dispatching posts to resolve target channelIds:

bash
# Inspect account details and default organization
buffer account --output json

# List all connected social channels (LinkedIn, X, Bluesky, Threads, Instagram, etc.)
buffer channels list --output json

# Get detailed metadata for a specific channel
buffer channels get --id "<channel-id>" --output json

Workflow B: Safe Post Creation & Scheduling #

Always execute with --dry-run first to validate the payload structure before sending live mutations:

bash
# Step 1: Dry run validation
buffer posts create \
  --channel-id "<channel-id>" \
  --scheduling-type automatic \
  --mode addToQueue \
  --text "Your post content here" \
  --dry-run

# Step 2: Live creation (Add to channel queue)
buffer posts create \
  --channel-id "<channel-id>" \
  --scheduling-type automatic \
  --mode addToQueue \
  --text "Your post content here" \
  --output json

Media Hosting Requirement (No File Upload Attachments) #

⚠️ WARNING

Buffer Does Not Support Direct File Uploads / Attachments: Buffer’s API and CLI do not accept raw binary file uploads or local file paths (such as path/to/image.png). To add media (images or videos) to a post, the files MUST be hosted somewhere publicly accessible via HTTP/HTTPS (e.g. S3 bucket, Cloud Storage, GitHub raw content, CDN, or image hosting service) so Buffer can ingest them via their public URLs.

Pass hosted media URLs via the assets array in a JSON payload:

json
{
  "channelId": "channel_123",
  "schedulingType": "automatic",
  "mode": "addToQueue",
  "text": "Announcing our new open-source release! 🚀",
  "assets": [
    {
      "image": {
        "url": "https://cdn.example.com/images/architecture-diagram.png",
        "metadata": {
          "altText": "Architecture diagram illustrating worker pool"
        }
      }
    }
  ]
}

For videos, provide the public video URL:

json
{
  "channelId": "channel_123",
  "schedulingType": "automatic",
  "mode": "addToQueue",
  "text": "Watch the terminal recording in action:",
  "assets": [
    {
      "video": {
        "url": "https://cdn.example.com/videos/demo.mp4"
      }
    }
  ]
}

Passing Payloads via JSON or File #

For complex multi-line text, media attachments, or structured objects:

bash
# Inline JSON payload with hosted media
buffer posts create --json '{
  "channelId": "channel_123",
  "schedulingType": "automatic",
  "mode": "addToQueue",
  "text": "Line 1\n\nLine 2 with links",
  "assets": [
    {
      "image": {
        "url": "https://cdn.example.com/diagram.png",
        "metadata": { "altText": "Architecture diagram" }
      }
    }
  ]
}' --output json

# Read payload from file
buffer posts create --input post_payload.json --output json

# Pipe payload from stdin
cat post_payload.json | buffer posts create --input - --output json

Workflow C: Drafting Ideas #

Create draft thoughts and ideas in Buffer without assigning them immediately to a channel queue:

bash
# Create an idea in an organization
buffer ideas create \
  --organization-id "<org-id>" \
  --text "Draft angle for next week's release" \
  --output json

# Create an idea with structured JSON
buffer ideas create --json '{
  "organizationId": "org_123",
  "content": { "text": "Architectural breakdown draft" }
}' --output json

Workflow D: Inspecting & Monitoring Scheduled Posts #

bash
# List recent posts on a channel
buffer posts list --channel-id "<channel-id>" --output json

# Fetch specific post status
buffer posts get --id "<post-id>" --output json

3. Field Selection (--fields) #

To minimize payload sizes and optimize context tokens, filter responses using comma-separated dot-notation paths or brace expansion:

bash
# Select top-level and nested properties
buffer posts get --id "<post-id>" --fields id,text,channel.name --output json

# Brace expansion for list connections
buffer posts list --channel-id "<channel-id>" --fields 'items.{id,text,status},pageInfo.endCursor' --output json

# Retrieve complete GraphQL payload
buffer posts get --id "<post-id>" --fields all --output json

4. Dynamic Schema Introspection #

When crafting payloads with unknown parameters or enums, query the live schema directly:

bash
# List all available command groups
buffer schema list

# Inspect exact input types, enum values, and output shapes for a command
buffer schema describe posts create

5. Global Flags & Exit Codes #

Global Flags #

FlagDescriptionBest Practice
--output <json|pretty|auto>Output renderer formatAlways specify --output json in agent tooling
--dry-runValidates input locally without network callsAlways run before stateful mutations
--quietSuppress spinners and stderr noticesRecommended for headless execution
--verbosePrint rate-limit summary after requestsUseful for debugging throughput limits
--timeout <ms>Command timeout in milliseconds (default: 30000)Set appropriately for large batch requests

Exit Code Reference #

Exit CodeClassificationCause & Agent Remediation
0SuccessCommand completed successfully.
1General ErrorRuntime failure. Check error message on stderr.
2Usage / Validation ErrorMissing required flags, invalid JSON, or schema mismatch. Run buffer schema describe <group> <cmd>.
3API ErrorGraphQL upstream error or rate limit exhaustion. Inspect returned error details.
4Authentication ErrorMissing or invalid token. Run buffer doctor or export BUFFER_API_KEY.

6. Critical Pitfalls & Payload Rules #

Review these high-risk failure modes before composing commands and JSON payloads:

1. Media Hosting & File Attachments #

  • Buffer Does Not Support Local Attachments: You cannot upload local file paths. All media (assets[].image.url or assets[].video.url) must be hosted publicly via HTTP/HTTPS (e.g. S3, GCS, CDN, or raw GitHub link).
  • Empty text without assets is rejected: Most channels require text or at least one image/video asset.

2. Scheduling Modes & Notification Traps #

  • mode: addToQueue is queued, not immediate: Use mode: shareNow to publish immediately. mode: shareNext jumps to the front of the queue. mode: customScheduled requires dueAt.
  • schedulingType: notification does not auto-publish: It only sends a push notification to the user’s mobile app. Always use schedulingType: automatic for hands-off publishing.
  • addToQueue on a channel with no schedule: Silently lands in an empty queue slot without scheduling. Check the schedule with buffer channels get --id <id> first.
  • All times must be ISO-8601 with offset: dueAt requires a timezone offset (e.g. 2026-05-06T17:00:00-05:00). Obtain the offset from buffer config get timezone or buffer account --fields timezone. Never assume UTC.

3. Identifier Integrity #

  • Never guess channel IDs: Always fetch with buffer channels list --output json. Invalid IDs will be accepted initially and fail on execution with vague upstream errors.
  • IDs are not portable across organizations: A channelId from Organization A cannot be used while authenticated against Organization B.

4. Input & Formatting Constraints #

  • --json overrides flags entirely: When both --json and individual flags are supplied, individual flags are ignored. Use either flags or --json, never mix.
  • Nested objects need --json: Per-service metadata.* and assets.* cannot be set via flat CLI flags. Always use --json or --input <file>.
  • Strip control characters: ASCII control characters (U+0000–U+001F except whitespace) cause payload rejections.

5. Per-Service Minimum Requirements & Threading #

  • Twitter / X, Threads, Bluesky, Mastodon: Require text only.
  • LinkedIn: text or assets; documents require metadata.linkedin.linkAttachment.
  • Instagram: Image or video asset required; must specify metadata.instagram.type and metadata.instagram.shouldShareToFeed.
  • Twitter / X Threads: When chaining posts via metadata.twitter.thread, the top-level text MUST match the first thread item’s text:
    json
    {
      "channelId": "ch_123",
      "text": "First tweet in thread",
      "metadata": {
        "twitter": {
          "thread": [
            { "text": "First tweet in thread" },
            { "text": "Second tweet in thread" }
          ]
        }
      }
    }