Skills wordpress-api-pro

install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/benkalsky/wordpress-api-pro" ~/.claude/skills/clawdbot-skills-wordpress-api-pro && rm -rf "$T"
manifest: skills/benkalsky/wordpress-api-pro/SKILL.md
source content

WordPress API

Interact with WordPress sites via the REST API. Create, update, and manage posts, pages, media, and more on any WordPress installation.

Quick Start

Single Site (Direct)

# Update a post
python3 scripts/update_post.py \
  --url "https://example.com" \
  --username "admin" \
  --app-password "xxxx xxxx xxxx xxxx" \
  --post-id 123 \
  --content "New content here" \
  --status "publish"

Multi-Site (CLI Wrapper) ⭐

# Setup: Copy config template and add your sites
cp config/sites.example.json config/sites.json
# Edit config/sites.json with your sites

# List configured sites
./wp.sh --list-sites

# Update post on specific site
./wp.sh digitizer-studio update-post --id 123 --content "New content"

# Run on all sites in a group
./wp.sh digitizer update-post --id 456 --status "publish"

# Batch update across multiple sites
python3 scripts/batch_update.py --group digitizer --post-ids 123,456 --status "publish"

Authentication

WordPress REST API supports two authentication methods:

1. Application Password (Recommended) ⭐

Setup:

  1. Go to:
    https://yoursite.com/wp-admin/profile.php
  2. Scroll to "Application Passwords"
  3. Name: "OpenClaw API" (or any name)
  4. Click "Add New Application Password"
  5. Copy the password (shows only once!)

Format:

xxxx xxxx xxxx xxxx xxxx xxxx
(24 characters with spaces)

Usage: Pass as

--app-password
to scripts or set
WP_APP_PASSWORD
environment variable

2. Basic Auth (Legacy)

Requires Basic Auth plugin. Less secure, not recommended for production.

Environment Variables

Set these to avoid passing credentials every time:

export WP_URL="https://example.com"
export WP_USERNAME="admin"
export WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx xxxx"

Multi-Site Management

Configuration

  1. Copy the example config:
cp config/sites.example.json config/sites.json
  1. Edit
    config/sites.json
    with your sites:
{
  "sites": {
    "my-site": {
      "url": "https://mysite.com",
      "username": "admin",
      "app_password": "xxxx xxxx xxxx",
      "description": "My WordPress site"
    }
  },
  "groups": {
    "all": ["my-site"]
  }
}

CLI Wrapper (
./wp.sh
)

# List sites
./wp.sh --list-sites
./wp.sh --list-groups

# Single site operations
./wp.sh my-site update-post --id 123 --content "..."
./wp.sh my-site create-post --title "..." --content "..."
./wp.sh my-site get-post --id 123
./wp.sh my-site list-posts --per-page 10

# Group operations (runs on all sites in group)
./wp.sh all update-post --id 123 --status "publish"

Batch Operations

# Update multiple posts across multiple sites
python3 scripts/batch_update.py \
  --group digitizer \
  --post-ids 123,456,789 \
  --status "publish"

# Update meta field on all sites
python3 scripts/batch_update.py \
  --sites all \
  --post-ids 100 \
  --meta-key "seo_score" \
  --meta-value "95"

# Dry run (see what would happen)
python3 scripts/batch_update.py \
  --group all \
  --post-ids 123 \
  --status "draft" \
  --dry-run

Individual Scripts

All scripts support both command-line arguments and environment variables.

Update Post

python3 scripts/update_post.py \
  --post-id 123 \
  --content "Updated content" \
  --title "New Title" \
  --status "publish"

Supports:

  • Content (HTML or Gutenberg blocks)
  • Title
  • Status (publish, draft, pending, private)
  • Featured image ID
  • Custom fields (meta)

Create Post

python3 scripts/create_post.py \
  --title "New Post" \
  --content "Post content" \
  --status "draft"

Get Post

python3 scripts/get_post.py --post-id 123

Returns full post data as JSON.

List Posts

python3 scripts/list_posts.py --per-page 10 --status "publish"

Options:

  • --per-page N
    - Posts per page (default: 10, max: 100)
  • --page N
    - Page number
  • --status STATUS
    - Filter by status (publish, draft, pending, private)
  • --author ID
    - Filter by author

Plugin Integration

Detect Plugins

Automatically detect installed WordPress plugins (ACF, Rank Math, Yoast, JetEngine):

python3 scripts/detect_plugins.py
python3 scripts/detect_plugins.py --verbose

ACF (Advanced Custom Fields)

Read and write ACF fields with automatic fallback to postmeta:

# Get all ACF fields
python3 scripts/acf_fields.py --post-id 123

# Get specific field
python3 scripts/acf_fields.py --post-id 123 --field my_field

# Set fields from JSON
python3 scripts/acf_fields.py --post-id 123 --set '{"field1": "value1", "field2": "value2"}'

# Set single field
python3 scripts/acf_fields.py --post-id 123 --field my_field --value "my value"

Features:

  • Automatic REST API detection with postmeta fallback
  • Support for simple, repeater, and group fields
  • JSON input/output for complex field structures

SEO Meta (Rank Math & Yoast)

Read and write SEO meta fields with auto-detection:

# Auto-detect plugin and get meta
python3 scripts/seo_meta.py --post-id 123

# Detect which SEO plugin is active
python3 scripts/seo_meta.py --post-id 123 --detect

# Get specific plugin's meta
python3 scripts/seo_meta.py --post-id 123 --plugin rankmath
python3 scripts/seo_meta.py --post-id 123 --plugin yoast

# Set SEO meta
python3 scripts/seo_meta.py --post-id 123 --set '{"title": "SEO Title", "description": "Meta description"}'

# Set with specific plugin
python3 scripts/seo_meta.py --post-id 123 --plugin rankmath --set '{"focus_keyword": "keyword"}'

Supported fields:

  • Rank Math: title, description, focus_keyword, robots, canonical_url, schema
  • Yoast: title, description, focus_keyword, canonical, meta_robots_noindex, meta_robots_nofollow

JetEngine Fields

Read and write JetEngine custom fields (stored as postmeta):

# Get all JetEngine fields
python3 scripts/jetengine_fields.py --post-id 123

# Get specific field
python3 scripts/jetengine_fields.py --post-id 123 --field my_field

# Set fields from JSON
python3 scripts/jetengine_fields.py --post-id 123 --set '{"field1": "value1", "field2": "value2"}'

# Set single field
python3 scripts/jetengine_fields.py --post-id 123 --field my_field --value "my value"

Elementor Content

Manage Elementor page builder content via

_elementor_data
meta field:

# Get Elementor data for a page
python3 scripts/elementor_content.py --post-id 123 --action get

# Update specific widget content
python3 scripts/elementor_content.py \
  --post-id 123 \
  --action update \
  --widget-id "abc123" \
  --content "New heading text"

Supported widget types:

  • Headings (
    heading
    )
  • Text Editor (
    text-editor
    )
  • Buttons (
    button
    )
  • Generic fallback for other widgets

How it works:

  • Gets page data with
    _elementor_data
    meta field
  • Parses JSON structure
  • Finds widget by ID (recursively through nested elements)
  • Updates content based on widget type
  • Saves back to WordPress

Media Upload

Upload images and files to WordPress media library:

# Upload local file
python3 scripts/upload_media.py \
  --file "/path/to/image.jpg" \
  --title "My Image" \
  --alt-text "Description for accessibility"

# Upload from URL
python3 scripts/upload_media.py \
  --file "https://example.com/image.jpg" \
  --title "Remote Image"

# Upload and set as featured image
python3 scripts/upload_media.py \
  --file "image.jpg" \
  --set-featured \
  --post-id 123

Features:

  • Supports local files and URLs
  • Auto-detects MIME type
  • Returns media ID for further operations
  • Can set as featured image in one call

WooCommerce Products

Manage WooCommerce products via REST API v3:

# List products
python3 scripts/woo_products.py \
  --consumer-key "ck_..." \
  --consumer-secret "cs_..." \
  --action list \
  --per-page 10

# Get single product
python3 scripts/woo_products.py \
  --consumer-key "ck_..." \
  --consumer-secret "cs_..." \
  --action get \
  --product-id 456

# Create product
python3 scripts/woo_products.py \
  --consumer-key "ck_..." \
  --consumer-secret "cs_..." \
  --action create \
  --title "New Product" \
  --price "29.99" \
  --description "Product description" \
  --status "publish"

# Update product
python3 scripts/woo_products.py \
  --consumer-key "ck_..." \
  --consumer-secret "cs_..." \
  --action update \
  --product-id 456 \
  --price "39.99" \
  --status "publish"

Authentication:

  • Requires WooCommerce Consumer Key and Consumer Secret
  • Get from: WooCommerce → Settings → Advanced → REST API
  • Environment variables:
    WC_CONSUMER_KEY
    ,
    WC_CONSUMER_SECRET

Supported fields:

  • --title
    /
    --name
    - Product name
  • --price
    - Regular price
  • --sale-price
    - Sale price
  • --description
    - Full description
  • --short-description
    - Short description
  • --status
    - publish, draft, pending, private
  • --sku
    - Stock keeping unit
  • --stock-quantity
    - Stock amount
  • --manage-stock
    - Enable stock management

Gutenberg Blocks

WordPress uses Gutenberg block format for content. See references/gutenberg-blocks.md for details.

Example block:

<!-- wp:paragraph -->
<p>This is a paragraph.</p>
<!-- /wp:paragraph -->

API Reference

See references/api-reference.md for complete WordPress REST API documentation.

Common endpoints:

  • /wp-json/wp/v2/posts
    - Posts
  • /wp-json/wp/v2/pages
    - Pages
  • /wp-json/wp/v2/media
    - Media
  • /wp-json/wp/v2/users
    - Users
  • /wp-json/wp/v2/categories
    - Categories
  • /wp-json/wp/v2/tags
    - Tags

Error Handling

All scripts return:

  • Exit code 0 on success
  • Exit code 1 on error
  • JSON output to stdout
  • Error messages to stderr

Security

  • DO: Use Application Passwords
  • DO: Use HTTPS only
  • DO: Store credentials in environment variables
  • DON'T: Hardcode passwords in scripts
  • DON'T: Use Basic Auth in production
  • DON'T: Commit credentials to git

Limitations

  • Requires WordPress 4.7+ (REST API built-in)
  • Requires Application Passwords plugin for WordPress <5.6
  • Some endpoints require specific user permissions
  • Rate limiting depends on host configuration