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.
wp2platform
Section titled “wp2platform”Spec: docs/openapi/wp2platform-modules.{en,ru}.yaml → /docs/api/wp2platform. Default auth: cookie / Application Password (DualRest), network.
Site Manager — wp2/site-manager/v1
Section titled “Site Manager — wp2/site-manager/v1”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 |
Multi Network — wp2/multi-network/v1
Section titled “Multi Network — wp2/multi-network/v1”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 |
Local Sync — wp2/local-sync/v1
Section titled “Local Sync — wp2/local-sync/v1”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 |
Course Manager — wp2/course-manager/v1
Section titled “Course Manager — wp2/course-manager/v1”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 |
Magic Links — wp2/magic-links/v1 (public)
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 |
Media Playback — wp2/media-playback/v1
Section titled “Media Playback — wp2/media-playback/v1”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 |
wp2lms
Section titled “wp2lms”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 |
Turbo — wp2lms/turbo/v1
Section titled “Turbo — wp2lms/turbo/v1”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 |
wp2lms-pro
Section titled “wp2lms-pro”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 |
wp2tutor
Section titled “wp2tutor”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 |
wp2tutor-forms
Section titled “wp2tutor-forms”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 |
wp2tutor-bot
Section titled “wp2tutor-bot”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-corelibrary as a separate API (License is documented under platform). - Themes / skin blocks, deprecated standalone plugins.
- WP2 Wrapper is a JS API, not WordPress REST.