Documentation / Reference
REST API reference
The plugin exposes 94 routes under /wp-json/wpcb/v1. The MCP server uses them, Xaflo Desktop uses them, and so can your own scripts: it is plain HTTPS and JSON, nothing AI-specific.
On this page
Base URL and authentication#
Every route lives under your site’s REST base. Send a token in the Authorization header:
curl
curl -H "Authorization: Bearer YOUR_TOKEN"
https://your-site.example/wp-json/wpcb/v1/whoami
If your host strips Authorization, send the same value in X-WPCB-Authorization.
Requests must use HTTPS; plain HTTP is answered with 426.
/health, /install/info and the two installer scripts are public. Token and plugin administration routes accept only a logged-in WordPress administrator, not a token.
The live list of routes is always at GET /wp-json/wpcb/v1, the standard WordPress namespace index.
Errors#
Errors use the WordPress REST format, with a code that starts with wpcb_:
JSON
{
"code": "wpcb_rate_limited",
"message": "…",
"data": { "status": 429, "retry_after": 12, "limit": 60, "scope_limited": "__global__" }
}
Status Code Meaning
400 wpcb_validationA parameter is missing or invalid.
401 wpcb_unauthorizedNo valid token.
403 wpcb_forbiddenMissing scope or WordPress capability.
426 wpcb_upgrade_requiredThe request was not over HTTPS.
428 wpcb_confirmation_requiredDestructive operation: repeat it with the confirmation_token returned.
428 wpcb_confirmation_invalidThe confirmation token is expired, used or for another operation.
429 wpcb_rate_limitedToo many requests; wait for Retry-After seconds.
400 wpcb_hash_mismatch, wpcb_invalid_packageAn uploaded zip does not match its SHA-256, or is not exactly one plugin.
403 xaflo_fs_outside_uploadsA file change outside the uploads folder without fs:admin.
409 wpcb_login_link_2fa and database refusalsSomething on the site stops the request: a two-factor sign-in plugin for quick login, or tables or MySQL settings /db/query cannot work with.
413 wpcb_too_largeAn uploaded zip over 20 MB or over the server’s upload limit.
Two-step confirmation#
Destructive operations answer the first call with 428 and a confirmation token instead of acting:
JSON · first response
{
"error": {
"code": "wpcb_confirmation_required",
"message": "Provide confirmation_token to restore.",
"confirmation_token": "ct_…",
"expires_at": "…",
"operation_summary": "…"
}
}
Repeat the same call with confirmation_token set to that value within five minutes. The token works once, for that operation, user and resource only; for writes it is also bound to the exact content, and for a plugin upload to the slug and the hash. MCP server 1.3 and Xaflo Desktop 2.0 never send it by themselves: they show the summary and wait for the person.
/db/query refusals carry their own codes, such as unsupported_placeholder, unknown_qualifier, cross_database, secret_column, protected_option or protected_table.
Health check#
GET /health needs no token and returns status, version, plugin_version, wp_version, php_version, site_url, rest_base, time and multilingual. Sent with a valid token, it also returns that token’s scopes (plugin 1.7.0). It is not written to the audit log.
New and changed in 1.7.0#
POST /admin/login-link (scope admin:login, administrator) returns {url, expires_in: 60}, a one-time sign-in link; an optional redirect_to must be a path under wp-admin. GET /admin/login-link/redeem is public and works once.
POST /plugins/install-zip also accepts zip_base64, filename and sha256 instead of zip_url; activation only with activate: true.
/fs/* writes: site:write inside uploads only, fs:admin elsewhere; confirmation_token accepted on write, upload, rename and delete; fs/write returns a backup id.
/media and /media/unused need media:read; /db/query needs an administrator; every token route checks a WordPress capability.
GET /plugins reports available updates and descriptions; WP-CLI values go in args.
All routes#
“Needs” lists the scopes for each method, in order. “admin” means the user behind the token must also be able to manage options; “admin session” means a logged-in administrator in the WordPress admin, with no token.
Identity, health and stats#
Route Methods Needs Does /healthGET public Plugin version, WordPress and PHP versions, site URL, time, multilingual adapter; with a valid token, also that token’s scopes. /whoamiGET auth:readThe user and scopes behind the token. /auditGET audit:read · adminThe audit log. /stats/dashboardGET dashboard:readDashboard statistics. /stats/timeseriesGET dashboard:readRequest counts over time.
Posts, pages, terms and search#
Route Methods Needs Does /postsGET · POST content:read · content:writeList or create posts. New posts are drafts unless the token has content:publish. /posts/{id}GET · PATCH · DELETE content:read · content:writeRead, update (a revision is saved first) or delete. Permanent delete asks for confirmation. /posts/{id}/publishPOST content:publishPublish a post. /pagesGET · POST content:read · content:writeList or create pages. /pages/{id}PATCH · DELETE content:writeUpdate or delete a page. Permanent delete asks for confirmation. /termsGET · POST content:read · content:writeList or create terms of a taxonomy. /searchGET content:readSearch across content.
Route Methods Needs Does /mediaGET media:readList the media library. /media/from-urlPOST media:writeSideload a file from a URL (SSRF-guarded). /media/from-base64POST media:writeUpload a base64-encoded file. /media/{id}PATCH · DELETE media:writeEdit alt text, caption and description; delete with confirmation. /media/{id}/optimizePOST media:writeOptimise an image. /media/unusedGET media:readMedia that no content uses.
SEO#
Route Methods Needs Does /seo/{post_id}GET · PATCH seo:read · seo:writeRead or write SEO meta for a post. /seo/{post_id}/analyzeGET seo:readAnalyse one post. /seo/auditGET seo:readAudit many posts. /seo/sitemapGET seo:readSitemap status. /seo/broken-linksGET seo:readBroken links in recent content or all of it.
Analytics#
Route Methods Needs Does /analytics/detectGET analytics:readWhich analytics source the site has. /analytics/overviewGET analytics:readTraffic overview. /analytics/top-postsGET analytics:readMost visited content. /analytics/top-referrersGET analytics:readTop referrers. /analytics/top-keywordsGET analytics:readTop search keywords. /analytics/post/{post_id}GET analytics:readTraffic for one post. /analytics/compareGET analytics:readCompare two periods. /analytics/trend-by-categoryGET analytics:readTrends per category. /analytics/no-traffic-pagesGET analytics:readPublished content without visits.
Multilingual#
Route Methods Needs Does /multilingual/detectGET content:readWhich multilingual plugin is active. /multilingual/languagesGET content:readSite languages. /multilingual/post/{post_id}/translationsGET · POST content:read · content:writeRead or link translations. /multilingual/post/{post_id}/languagePATCH content:writeSet the language of a post. /multilingual/media/{attachment_id}/translationsGET content:readMedia translations. /multilingual/media/{attachment_id}/translations/{language_code}PATCH media:writeTranslate media metadata. /multilingual/media/auditGET content:readMedia translation coverage. /multilingual/stringsGET content:readString translations. /multilingual/strings/auditGET content:readString translation coverage.
Theme#
Route Methods Needs Does /themeGET theme:readThe active theme. /theme/filesGET · PUT theme:read · theme:writeList files, or write one (the previous version is kept). /theme/files/readGET theme:readRead a theme file. /theme/custom-cssPOST theme:writeAdd custom CSS. /theme/switchPOST theme:writeSwitch theme, with confirmation.
Plugins#
Route Methods Needs Does /pluginsGET plugin:readInstalled plugins. /plugins/{slug}/files/readGET plugin:readRead a plugin file. /plugins/{slug}/filesPUT plugin:writeWrite a plugin file. /plugins/scaffoldPOST plugin:installCreate a new plugin skeleton. /plugins/install-zipPOST plugin:installInstall from a zip URL, or from a zip in the request (zip_base64, filename, sha256; at most 20 MB). Replacing an installed plugin asks for confirmation. /plugins/install-repoPOST plugin:installInstall from the WordPress.org directory, with confirmation. /plugins/{slug}/activatePOST plugin:installActivate a plugin. /plugins/{slug}/deactivatePOST plugin:installDeactivate a plugin.
Settings, menus, widgets#
Route Methods Needs Does /settingsGET · POST site:read · site:writeRead or change settings. Changing siteurl, home or admin_email asks for confirmation. /menusGET · POST site:read · site:writeList or create menus. /menus/{id}PATCH site:writeUpdate a menu. /widgetsGET · POST site:read · site:writeRead or set widgets. /customizerGET · POST site:read · site:writeRead or set Customizer values. /performanceGET site:readSystem, database, cache and disk information.
Backups#
Route Methods Needs Does /backupGET · POST system:backup · adminList backups, or create one (database, files or both). /backup/{id}/restorePOST system:backup · adminRestore a backup, with confirmation.
Maintenance mode and debug log#
Route Methods Needs Does /maintenanceGET · POST · DELETE site:read · site:write · adminStatus, turn on, turn off. /maintenance/previewGET site:read · adminRender the 503 page without enabling it. /debug/logGET · DELETE audit:read · site:write · adminTail or clear debug.log. /debug/log/statusGET audit:read · adminSize and state of debug.log.
Files#
Route Methods Needs Does /fs/listGET site:read · adminList a directory. /fs/readGET site:read · adminRead a file. /fs/downloadGET site:read · adminDownload a file. /fs/searchGET site:read · adminFind files by name. /fs/writePUT site:write · fs:admin · adminWrite a file: inside uploads with site:write, elsewhere with fs:admin (overwrites confirmed). /fs/mkdirPOST site:write · fs:admin · adminCreate a directory. /fs/renamePOST site:write · fs:admin · adminRename or move, with confirmation under fs:admin. /fs/uploadPOST site:write · fs:admin · adminUpload a file. /fs/deleteDELETE · POST site:write · fs:admin · adminDelete, with confirmation; recursive for folders.
Database and WP-CLI#
Route Methods Needs Does /db/queryPOST db:read · db:write · adminSQL through the guard. Writes need mode write, db:write, InnoDB tables and confirmation. /cliPOST cli:exec · adminAllowlisted WP-CLI commands. Off until the site owner enables it.
Quick login#
Route Methods Needs Does /admin/login-linkPOST admin:login · adminA one-time link, valid 60 seconds, that signs the token’s own user in to wp-admin. /admin/login-link/redeemGET public Uses a sign-in link once. Every refusal redirects to wp-login.php.
Plugin administration#
Route Methods Needs Does /tokensGET · POST admin session List or create tokens. /tokens/{jti}DELETE admin session Revoke a token. /scopesGET admin session All scopes with descriptions. /jwt-secret-suggestGET admin session A fresh secret value. /admin/settingsGET · POST admin session Plugin settings. /admin/cleanup-nowPOST admin session Run the daily cleanup now. /admin/jwt-secret/statusGET admin session Whether the secret is set. /admin/jwt-secret/installPOST admin session Write a new secret into wp-config.php. /admin/jwt-secret/rotatePOST admin session Replace the secret, which invalidates every token. /admin/jwt-secret/removePOST admin session Remove the secret. /admin/routesGET admin session The live route list. /install/infoGET public MCP package version and installer URLs. /install/script.shGET public Installer script for bash. /install/script.ps1GET public Installer script for PowerShell. /install/bundlePOST admin session Installer bundle.