by Digitizers
🔧 Manage WordPress sites via REST API — posts, media, Elementor, WooCommerce, ACF, Rank Math. Multi-site support.
# Add to your Claude Code skills
git clone https://github.com/Digitizers/wordpress-api-proInteract with WordPress sites via the REST API. Create, update, and manage posts, pages, media, and more on any WordPress installation.
# 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"
# 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"
WordPress REST API supports two authentication methods:
Setup:
https://yoursite.com/wp-admin/profile.phpFormat: xxxx xxxx xxxx xxxx xxxx xxxx (24 characters with spaces)
Usage: Pass as --app-password to scripts or set WP_APP_PASSWORD environment variable
WordPress REST API integration skill for OpenClaw. Manage posts, pages, media, and more programmatically.
clawhub install wordpress-api-pro
cd ~/.openclaw/workspace/skills/
git clone https://github.com/Digitizers/wordpress-api-pro wordpress-api-pro
1. Copy config template:
cd ~/.openclaw/workspace/skills/wordpress-api-pro
cp config/sites.example.json config/sites.json
2. Edit config/sites.json:
No comments yet. Be the first to share your thoughts!
Requires Basic Auth plugin. Less secure, not recommended for production.
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"
cp config/sites.example.json config/sites.json
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"]
}
}
./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"
# 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
All scripts support both command-line arguments and environment variables.
python3 scripts/update_post.py \
--post-id 123 \
--content "Updated content" \
--title "New Title" \
--status "publish"
Supports:
python3 scripts/create_post.py \
--title "New Post" \
--content "Post content" \
--status "draft"
python3 scripts/get_post.py --post-id 123
Returns full post data as JSON.
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 authorAutomatically detect installed WordPress plugins (ACF, Rank Math, Yoast, JetEngine):
python3 scripts/detect_plugins.py
python3 scripts/detect_plugins.py --verbose
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:
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:
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"
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:
heading)text-editor)button)How it works:
_elementor_data meta fieldUpload 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:
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:
WC_CONSUMER_KEY, WC_CONSUMER_SECRETSupported 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 managementWordPress 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 -->
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 - TagsAll scripts return:
{
"sites": {
"site1": {
"url": "https://site1.com",
"username": "admin",
"app_password": "xxxx xxxx xxxx",
"description": "First site"
},
"site2": {
"url": "https://site2.com",
"username": "admin",
"app_password": "yyyy yyyy yyyy",
"description": "Second site"
}
},
"groups": {
"all": ["site1", "site2"]
}
}
3. Use the CLI wrapper:
# List sites
./wp.sh --list-sites
# Update post on specific site
./wp.sh site1 update-post --id 123 --content "New content"
# Update on all sites
./wp.sh all update-post --id 456 --status "publish"
# Batch update
python3 scripts/batch_update.py --group all --post-ids 123,456 --status "publish"
https://yoursite.com/wp-admin/profile.phpexport WP_URL="https://yoursite.com"
export WP_USERNAME="your-username"
export WP_APP_PASSWORD="xxxx xxxx xxxx xxxx xxxx xxxx"
Update a post:
python3 ~/.openclaw/workspace/skills/wordpress-api-pro/scripts/update_post.py \
--post-id 123 \
--title "New Title" \
--content "Updated content" \
--status "publish"
Create a post:
python3 scripts/create_post.py \
--title "My Post" \
--content "Post content here" \
--status "draft"
Get a post:
python3 scripts/get_post.py --post-id 123
List posts:
python3 scripts/list_posts.py --per-page 10 --status "publish"
| Script | Purpose |
|--------|---------|
| update_post.py | Update existing post |
| create_post.py | Create new post |
| get_post.py | Retrieve single post |
| list_posts.py | List/filter posts |
| Script | Purpose |
|--------|---------|
| detect_plugins.py | Auto-detect installed plugins (ACF, Rank Math, Yoast, JetEngine) |
| acf_fields.py | Read/write Advanced Custom Fields |
| seo_meta.py | Read/write Rank Math & Yoast SEO meta |
| jetengine_fields.py | Read/write JetEngine custom fields |
| elementor_content.py | Read/update Elementor page content |
| upload_media.py | Upload images to WordPress media library |
| woo_products.py | Manage WooCommerce products |
Examples:
# Detect plugins
python3 scripts/detect_plugins.py
# Get ACF fields
python3 scripts/acf_fields.py --post-id 123
# Set SEO meta
python3 scripts/seo_meta.py --post-id 123 --set '{"title": "SEO Title", "description": "Meta desc"}'
# Update JetEngine field
python3 scripts/jetengine_fields.py --post-id 123 --field my_field --value "value"
# Elementor Content
python3 scripts/elementor_content.py get --post-id 123 --widget-id some_widget_id
python3 scripts/elementor_content.py update --post-id 123 --widget-id some_widget_id --field 'title' --value 'New Title'
# Media Upload
python3 scripts/upload_media.py --file-path /path/to/image.jpg --title "My Image" --caption "A beautiful image"
python3 scripts/upload_media.py --url https://example.com/image.png --set-featured --post-id 123
# WooCommerce Products
python3 scripts/woo_products.py list --status 'publish'
python3 scripts/woo_products.py get --id 456
python3 scripts/woo_products.py create --name "New Product" --type 'simple' --regular-price '29.99'
python3 scripts/woo_products.py update --id 456 --description "Updated product description"
requests library (for plugin integration scripts): pip install requestsMIT License - See LICENSE.txt
Built with ❤️ for OpenClaw by Digitizer