Skip to content

REST Endpoint Inventory

Phase 3: canonical YAML is a full contract (requestBody / security / WpError / response codes), not only a path catalog. URLs are {product}/{slug}/v1.

Canonical YAML lives in each plugin as docs/openapi/<base>.{en,ru}.yaml (e.g. wp2platform-modules.en.yaml). The site copies specs (npm run sync:openapi → openapi-specs/{en,ru}/<base>.yaml) and generates MDX (npm run gen-api-docs). Path/depth audit: npm run audit:openapi (body or x-empty-body, security, ru/en status codes). Scanner exclusions: vendor, vendor-lib, tests, includes/analogwp-*. License is registered from wp2platform/plugin.php through the wordpress-core controller and is added to the audit explicitly.

Contract size (EN): 137 operations in the product YAMLs below. Live functional check on stage (Application Password): harness .cursor/skills/remote-ssh-wp/scripts/stage_openapi_e2e/ — target 137 PASS. Multi-network REST appears on stage only after committed setup (wp2platform_multi_network_committed); otherwise the path exists in YAML but not in rest_get_server().

OpenAPI column: contract — the operation is described in YAML with input/output/errors.

WP_REST_Server::EDITABLE in PHP = POST|PUT|PATCH; OpenAPI usually documents PATCH (this is sufficient for coverage). CREATABLE = POST, READABLE = GET, DELETABLE = DELETE.


Spec: docs/openapi/wp2platform-modules.{en,ru}.yaml → /docs/api/wp2platform. Default auth: cookie / Application Password (DualRest), network.

Clients: Site Manager admin UI. blog_id in path.

METHOD Path OpenAPI
GET /wp-json/wp2/site-manager/v1/sites contract
POST …/sites contract
GET …/sites/slug-availability contract
POST …/sites/bulk contract
GET …/sites/{blog_id} contract
PATCH (EDITABLE) …/sites/{blog_id} contract
DELETE …/sites/{blog_id} contract
POST …/sites/{blog_id}/archive contract
POST …/sites/{blog_id}/unarchive contract
POST …/sites/{blog_id}/activate contract
POST …/sites/{blog_id}/deactivate contract
GET …/sites/{blog_id}/users contract
POST …/sites/{blog_id}/users contract
DELETE …/sites/{blog_id}/users/{user_id} contract
GET/POST …/categories contract
PATCH/DELETE …/categories/{id} contract
GET/POST …/statuses contract
PATCH/DELETE …/statuses/{id} contract
GET …/jobs contract
GET …/jobs/{job_id} contract
GET …/jobs/{job_id}/events contract

Site Duplicator — wp2/site-duplicator/v1

Section titled “Site Duplicator — wp2/site-duplicator/v1”
METHOD Path OpenAPI
POST /wp-json/wp2/site-duplicator/v1/sites/{blog_id}/duplicate contract
GET …/jobs, …/jobs/{job_id}, …/jobs/{job_id}/events contract

Post Duplicator — wp2/post-duplicator/v1

Section titled “Post Duplicator — wp2/post-duplicator/v1”
METHOD Path OpenAPI
POST /wp-json/wp2/post-duplicator/v1/posts/{post_id}/duplicate contract
POST …/posts/{post_id}/duplicate-batch contract

Runtime: the module boots only with a committed multi-network setup; without it the routes exist in OpenAPI but not on the site.

METHOD Path OpenAPI
GET/POST /wp-json/wp2/multi-network/v1/networks contract
GET …/networks/{network_id} contract

Media Converter — wp2/media-converter/v1

Section titled “Media Converter — wp2/media-converter/v1”

Clients: media-hls-encode, media-whisper-tracks skills (formats, attachments, artifacts/pack). Query blog_id on some endpoints.

METHOD Path OpenAPI
GET …/media-converter/v1/formats contract
GET/PATCH …/settings contract
POST …/media, …/encode contract
GET …/attachments/{id} contract
POST …/attachments/{id}/encode contract
GET …/queue, …/queue/{key} contract
POST …/queue/control, …/queue/clear contract
DELETE …/queue/{key} contract
POST …/queue/{key}/formats/{format}/cancel contract
GET/POST/DELETE …/attachments/{id}/frame-miniatures contract
GET/POST …/attachments/{id}/thumbnails contract
PATCH/DELETE …/attachments/{id}/thumbnails/poster contract
GET …/attachments/{id}/artifacts contract
POST …/attachments/{id}/artifacts/pack contract
PATCH/DELETE …/attachments/{id}/artifacts/{folder} contract

Subtitles & Timecodes — wp2/media-subtitles-timecodes/v1

Section titled “Subtitles & Timecodes — wp2/media-subtitles-timecodes/v1”

Client: media-whisper-tracks skill.

METHOD Path OpenAPI
GET/POST/PUT …/media-subtitles-timecodes/v1/attachments/{id}/tracks contract
POST …/tracks/upload contract
PATCH/DELETE …/tracks/{index} contract

Enable Media Replace — wp2/enable-media-replace/v1

Section titled “Enable Media Replace — wp2/enable-media-replace/v1”
METHOD Path OpenAPI
GET …/enable-media-replace/v1/attachments/{id}/replace-info contract
POST …/attachments/{id}/replace contract

Error: playback_artifacts_present (409) if playback artifacts are associated with the attachment.

Studio Sync — wp2/studio-sync/v1 (already the phase 2 canonical form)

Section titled “Studio Sync — wp2/studio-sync/v1 (already the phase 2 canonical form)”

Client: WP2Studio (STUDIO_SYNC_REST_BASE). Auth: public on POST /desktop/connect; then Bearer. PHP: src/Modules/StudioSync/. Do not rework.

METHOD Path Auth OpenAPI
POST /wp-json/wp2/studio-sync/v1/desktop/connect public (one-time token) contract
GET …/desktop/status Bearer contract
POST …/desktop/disconnect Bearer contract
GET …/sites Bearer contract
GET …/status Bearer (legacy) contract
GET …/sync/items Bearer contract
GET …/sync/posts/{post_id} Bearer contract
PATCH (EDITABLE) …/sync/posts/{post_id} Bearer, body base_hash+content contract

Clients: 09-local-sync skill, page-builder pipeline (POST /validate). Capability: manage_network (MS) / edit_pages. Query blog_id.

METHOD Path OpenAPI
GET /wp-json/wp2/local-sync/v1/projects contract
POST …/sync contract
POST …/validate contract

Client: Gutenberg sidebar admin UI. manage_categories + edit_posts. Creating/deleting sections uses core /wp/v2/{taxonomy}, not this API.

METHOD Path OpenAPI
GET /wp-json/wp2/course-manager/v1/sidebar contract
PUT …/reorder contract
PUT …/assign contract
PATCH (EDITABLE) …/sections/{id} contract

Passwordless — wp2/passwordless/v1 (public)

Section titled “Passwordless — wp2/passwordless/v1 (public)”

Client: WP2 Platform login forms.

METHOD Path OpenAPI
POST /wp-json/wp2/passwordless/v1/request contract
POST …/verify contract
Section titled “Magic Links — wp2/magic-links/v1 (public)”

Client: consume interstitial in WP2 Platform.

METHOD Path OpenAPI
POST /wp-json/wp2/magic-links/v1/consume contract

Elementor Style Presets — wp2/elementor-style-presets/v1

Section titled “Elementor Style Presets — wp2/elementor-style-presets/v1”

Client: Elementor admin UI. edit_posts. Module can_be_enabled only when Elementor is installed.

METHOD Path OpenAPI
GET/POST /wp-json/wp2/elementor-style-presets/v1/presets contract
GET …/presets/{id} contract
PATCH (EDITABLE) …/presets/{id} contract

Clients: players (Vidstack and others). Query blog_id, lang.

METHOD Path OpenAPI
GET /wp-json/wp2/media-playback/v1/attachments/{id} contract

License — wp2/license/v1 (platform product)

Section titled “License — wp2/license/v1 (platform product)”

Registration: plugin.php → LicenseRestController('wp2', 'license', $hub). The wp2-wordpress-core repository is not documented separately. Auth: manage_network_options / manage_options.

METHOD Path OpenAPI
GET /wp-json/wp2/license/v1/products contract
POST …/{product_id}/activate contract
POST …/{product_id}/deactivate contract
GET …/{product_id}/status contract
GET …/{product_id}/data contract

Spec: docs/openapi/wp2lms.{en,ru}.yaml.

Static Builder — wp2lms/static-builder/v1

Section titled “Static Builder — wp2lms/static-builder/v1”

Clients: 10-static-builder skill, CLI bin/static-builder/*. Auth: edit_pages / manage_network. Query blog_id.

WP_Error: wp2lms_static_builder_invalid_blog, blog_not_found, busy, not_found, no_pages, cannot_stop, invalid_id, invalid_api_type, invalid_version, invalid_export_mode, pages_required, invalid_page_ids, page_not_found, create_failed, configure_failed, update_failed, delete_failed, page_cache_rebuild.

METHOD Path OpenAPI
GET /wp-json/wp2lms/static-builder/v1/pages contract
GET/POST …/builds contract
GET/PATCH/DELETE …/builds/{id} contract
POST …/builds/{id}/run contract
POST …/builds/{id}/stop contract

Clients: Turbo frontend (Gutenberg/Twig), Gravity Forms bridge, xAPI session.

METHOD Path Auth OpenAPI
POST /wp-json/wp2lms/turbo/v1/xapi-actor/session cookie (email) contract
POST …/gravity-forms/submit cookie contract
POST …/dsh/expand cookie contract
GET …/static/{id} edit_posts contract

Spec: docs/openapi/wp2lms-pro.{en,ru}.yaml.

Embed Packages — wp2lms-pro/embed-packages/v1

Section titled “Embed Packages — wp2lms-pro/embed-packages/v1”

The wp2platform/module/embed-packages/v1 alias is removed. Auth: manage_network / edit_pages. Query blog_id.

WP_Error: embed_packages_not_found, delete_failed, page_not_found, invalid_blog, unknown_blog.

METHOD Path OpenAPI
GET/POST /wp-json/wp2lms-pro/embed-packages/v1/packages contract
GET/PATCH/DELETE …/packages/{id} contract
POST …/packages/{id}/content contract
POST …/packages/{id}/materialize-pages contract
GET/PUT/DELETE …/pages/{page_id}/package contract
POST …/batch contract

Spec: docs/openapi/wp2tutor.{en,ru}.yaml. Namespaces are split per module. Bot is not in this spec (see wp2tutor-bot). RAG routes register when module rag is enabled and rag_export_enabled is on.

METHOD Path Auth OpenAPI
GET / POST /wp-json/wp2tutor/ai/v1/chat GET public; POST X-Ai-Chat-Secret contract
POST /wp-json/wp2tutor/embedding/v1/sync manage_options contract
POST …/statuses manage_options contract
POST …/diagnostics manage_options contract
GET/POST /wp-json/wp2tutor/rag/v1/datatables admin contract
GET …/chunk/{id_chunk} admin contract

Spec: docs/openapi/wp2tutor-forms.{en,ru}.yaml. Own namespaces wp2tutor-forms/form/v1 and wp2tutor-forms/i18n/v1 (not shared wp2tutor/v1). Form: cookie / Application Password (logged-in). i18n: public. Module wp2tutor_form via the platform modules list.

METHOD Path OpenAPI
POST /wp-json/wp2tutor-forms/form/v1/updateDefinition contract
POST …/updateShortcode contract
POST …/updateStyles contract
POST …/updateL10n contract
POST …/updateRunner contract
GET …/getRunnerData contract
GET /wp-json/wp2tutor-forms/i18n/v1/locale contract
GET …/translation contract

Spec: docs/openapi/wp2tutor-bot.{en,ru}.yaml. Public webhooks. Change the URL in Telegram/VK when deploying.

METHOD Path Auth OpenAPI
POST /wp-json/wp2tutor-bot/telegram/v1/webhook/{bot_id} public contract
POST /wp-json/wp2tutor-bot/vk/v1/callback/{channel_id} public contract
POST /wp-json/wp2tutor-bot/deepchat/v1/chat/{channel_id} public + X-Wp2tutor-Bot-Secret contract
OPTIONS …/chat/{channel_id} public CORS contract

Clients: Telegram/VK, Deep Chat UI (channel secret is not in the client bundle).


Out of scope (intentionally absent from product YAML)

Section titled “Out of scope (intentionally absent from product YAML)”
  • AJAX admin-ajax.php, WP-CLI.
  • Core /wp/v2/*, AnalogWP REST, third-party Elementor/WPML namespaces.
  • The wp2-wordpress-core library as a separate API (License is documented under platform).
  • Themes / skin blocks, deprecated standalone plugins.
  • WP2 Wrapper is a JS API, not WordPress REST.