API ReferenceAPI Reference

API Reference

Complete REST API reference for Respira for WordPress, including v1 and v2 endpoints for pages, posts, builders, snapshots, and more.

Overview

Respira for WordPress exposes a comprehensive REST API for managing your WordPress site with duplicate-first safety, builder-aware updates, and fidelity workflows.

This REST API underpins multiple Respira surfaces:

  • the standalone Respira MCP server
  • the official WordPress Abilities + MCP Adapter integration
  • built-in Browser AI/WebMCP
  • the curated Elementor Angie bridge

Base URLs

Respira currently exposes two namespaces:

https://your-site.com/wp-json/respira/v1/
https://your-site.com/wp-json/respira/v2/
  • v1: broad compatibility endpoints used across older and mixed environments
  • v2: capability negotiation, fidelity/snapshot flows, and builder patch operations

Browser-auth Angie endpoints use a separate namespace:

https://your-site.com/wp-json/respira/browser/v1/

See Elementor Angie for the browser-auth flow, and WordPress AI Stack Compatibility for the official Abilities/MCP Adapter path.

Capability status endpoint (v2)

Use this endpoint to detect v2 feature support:

GET /wp-json/respira/v2/status

Authentication

Include your API key with every request:

X-Respira-API-Key: respira_your-api-key-here

Site Context

Get site context

Returns comprehensive information about the WordPress site including version, theme, plugins, and detected page builders.

GET /context/site-info

Get theme docs

Returns theme documentation and available template files.

GET /context/theme-docs

Get builder info

Returns information about the active page builder including available modules/widgets.

GET /context/builder-info

Snapshots and fidelity (v2)

Snapshot endpoints support safer compare/restore flows:

GET /snapshots
GET /snapshots/{uuid}
POST /snapshots/diff
POST /snapshots/restore

Builder patch endpoint:

POST /builder/{builder}/patch/{post_id}

Pages

Bind an edit or approval to the reviewed version

Reads and writes for one page return content_version and content_version_post_id. Treat the version as an opaque string: store it unchanged and compare for equality only. Do not parse it, sort it, increment it or construct it yourself.

The current format is v2- followed by 24 lowercase hexadecimal characters, for example v2-bac62a0329c59755b20bb40e. It is a deterministic hash of the stored builder payload, page content, title, status and supported SEO fields. Changing any of those can change the value. An unchanged state keeps the same value; returning to an earlier state can return an earlier value. It is not a timestamp, revision counter or proof that the public page head has refreshed.

The format is stable within a plugin minor release line unless the changelog announces a format change. Plugin 9.2.10 changed the prefix from v1- to v2- because SEO fields joined the hash. A held v1- token is still checked against the old content-only material for compatibility. For SEO approval, read a current v2- token rather than reusing a token from before the upgrade.

Send the version from the page or draft you reviewed on each write:

PUT /wp-json/respira/v2/pages/123
Content-Type: application/json
X-Respira-API-Key: YOUR_KEY

{"expected_version":"v2-bac62a0329c59755b20bb40e","seo":{"description":"Reviewed description"}}

A successful write returns the new version. A duplicate-first write returns the draft's ID and version, because that is where the edit landed. Review that draft, then approve its current version:

POST /wp-json/respira/v2/duplicates/123/approve
Content-Type: application/json
X-Respira-API-Key: YOUR_KEY

{"expected_version":"VERSION_RETURNED_FOR_THE_REVIEWED_DRAFT"}

If it changed, the request returns HTTP 409 respira_version_conflict and performs no write. A stale or made-up value is refused; an empty or non-text value is refused. force does not override a version conflict. Read the draft again and have the changed version reviewed before approving it. Omitting a version on legacy duplicate approvals provides no version binding.

After an approval, content_version_post_id identifies the live page. Use that ID when checking the stored result and fetch the public page separately to verify what visitors receive.

Published content with incomplete SEO

From plugin 9.2.12, approval returns HTTP 200 when the content is live even if an SEO field fails read-back. Check complete, not only the HTTP status or success. The response names the fields in warnings and retains the respira_approve_seo_not_carried code:

{
  "success": true,
  "published": true,
  "complete": false,
  "live_post_id": 42,
  "warnings": [{
    "code": "respira_approve_seo_not_carried",
    "fields": [{
      "field": "_yoast_wpseo_metadesc",
      "where": "yoast_indexable",
      "expected": "Reviewed description",
      "actual": null
    }]
  }]
}

This replaces the HTTP 500 response for this partial outcome in 9.2.10 and 9.2.11. Update integrations that relied on that status. A completed approval returns published: true, complete: true and an empty warnings array. Version conflicts and permission refusals remain non-2xx. A partial approval has already changed the public page: do not retry the same approval. Read the live page and decide whether to repair its SEO through another reviewed draft or ask an administrator to restore the saved snapshot.

Reviewed menu and redirect changes

Plugin 9.2.13 adds a separate pending-change workflow. A Publish only key can propose, read, approve, reject and undo these changes. Its direct menu and redirect write routes remain forbidden (HTTP 403).

All paths below start at /wp-json/respira/v2. Use your site key in X-Respira-API-Key. Cookie-authenticated administrators use the WordPress REST nonce. Records are private and local to this WordPress site.

Method and pathResult
GET /pending-changes/target?target[kind]=menu&target[id]=3Complete state and target version for one existing classic menu.
GET /pending-changes/target?target[kind]=redirectsComplete readable redirect list and target version.
POST /pending-changesSave exact target, before, after and optional expires_in seconds. No live write.
GET /pending-changes/{id}Full proposal, versions, author key/user, creation, expiry, status and receipt.
POST /pending-changes/{id}/approveRequire expected_version from the proposal that was reviewed.
POST /pending-changes/{id}/rejectReject an unexpired proposal without changing the live target.
POST /pending-changes/{id}/undoCreate a reverse proposal; approve it separately.
GET /pending-changes?status=pending&page=1&per_page=25Paginated site history, optionally filtered by status and target[kind]/target[id].
POST /pending-changes/expireMark up to 100 expired records per call; repeat while remaining is positive. No live write.
  1. Read the target. Copy its entire state into both before and after.
  2. Edit only after. Save { "target": {"kind":"menu","id":3}, "before": ORIGINAL_STATE, "after": PROPOSED_STATE }.
  3. Read the returned change by its ID. Show the full before/after to the approver and retain that change's version unchanged.
  4. Approve with { "expected_version": "VERSION_FROM_THE_REVIEWED_CHANGE" }.
  5. Inspect published, complete, warnings, applied and actual_after, then check the public URLs separately.

The pending version (pc1-…) binds the exact proposal, author, site and expiry. The target_version (pt1-…) binds the live menu or redirect configuration. Both are opaque strings, distinct from page content_version. Creation refuses stale before with HTTP 409 respira_version_conflict. Approval returns the same 409 if the reviewed proposal or the live target changed. There is no force override. A busy target returns 423; an expired proposal returns 410.

Menu v1 edits items: add, update, remove, reorder and parent relationships. Keep the menu's name, description, theme, configuration and locations unchanged. Copy every existing item's fields and integer ID. New items use a unique new:client-reference, configuration: null and consecutive positions starting at 1; a parent is 0 or another ID/reference in the proposed menu. For a custom link use type: "custom", object: "custom", object_id: 0 and a safe URL. Published post links, taxonomy links and post type archives must match their current URLs. Cycles and missing targets or parents are refused.

Redirect v1 edits rules in the full state, retaining engines unchanged. Existing IDs are engine-qualified, such as respira:2 or redirection:5. New rules use new:client-reference, configuration: null, a writable engine (respira or active redirection), source, target, match (exact or regex), query mode (ignore, exact or pass), status code, enabled flag and note. Other redirect managers remain read-only. Unsafe schemes, duplicate sources, loops and protected WordPress URLs are refused. Use canonical paths; validation refuses proposals that would need silent normalization.

A complete target snapshot is limited to 1,000 items/rules. A redirect proposal may change at most 50 rules, with at most 200 native regular expressions. Oversize or incomplete reads are refused. Default expiry is seven days; expires_in accepts 1 through 2,592,000 seconds (30 days). List status values are pending, applying, applied, rejected and expired; per_page is capped at 100. Expiry preserves history and applied receipts.

Approval reads the target back and stores a durable receipt:

{
  "published": true,
  "complete": false,
  "warnings": [{
    "code": "respira_pending_change_not_carried",
    "fields": [{"field":"target.items.0.title","where":"stored_target","expected":"Reviewed title","actual":"Filtered title"}]
  }],
  "applied": {"created":[45],"updated":[],"removed":[],"references":{"new:link":45}}
}

HTTP 200 alone does not mean complete. A partial receipt includes the expected and actual states, attempted writes and cache purge report. Repeating an applied approval with the same reviewed version returns that stored receipt without applying again, including an incomplete receipt. Read it and propose a reviewed repair or undo. An interrupted applying record refuses blind re-execution; inspect the live target before recovery.

Undo's before is the current target and its after is the saved prior state. Review it carefully: restoring that state can also remove changes made since the original approval. Nothing goes live until the undo's own version is approved. Recreating deleted entries allocates new engine IDs; the receipt maps those IDs. Ordinary new entries use engine defaults. Undo retains the saved configuration for recreated entries, including menu metadata and writable Redirection options; read-back reports a mismatch if an integration changes that restored state.

Menus can appear throughout a site, so resource approval calls the shared site-wide cache purge path. cache_purge reports the integrations called; it does not prove a host/CDN cache was cleared or that a visitor received the new page. Fetch the public URL to verify it.

The npm server (8.6.8+) exposes wordpress_read_change_target, wordpress_create_pending_change, wordpress_get_pending_change, wordpress_list_pending_changes, wordpress_approve_pending_change, wordpress_reject_pending_change, wordpress_undo_pending_change and wordpress_expire_pending_changes (also listed with the respira_ prefix). The native endpoint exposes the same eight operations as respira_wordpress_*. In wp-admin, proposals appear in Respira → Activity → Approval queue for individual review.

Create a new page with a Publish only key

From plugin 9.2.12, use the existing creation endpoint:

POST /wp-json/respira/v1/post-types/page/posts
Content-Type: application/json
X-Respira-API-Key: YOUR_KEY

{"type":"page","title":"New page","content":"<h1>Review this page</h1>","status":"draft"}

For this key profile, creation accepts title, content, slug and excerpt. New page drafts include slug and excerpt in their version token, so changing either after review invalidates approval. status defaults to draft; other statuses and post types are refused. Author changes, taxonomy creation and arbitrary metadata are refused. Edit the returned page through PUT /respira/v2/pages/{id} and set its SEO there. Review it, then call POST /respira/v2/duplicates/{id}/approve with its current content_version as expected_version. Approval publishes the new page at the same ID, with approval_mode: "publish_new_page". The version is required for this path and force-publishing is refused. Direct menu and redirect writes remain outside this key's permissions; use pending changes for those targets.

List pages

List all pages with optional filtering.

GET /pages

Query parameters:

  • status - Filter by status (publish, draft, pending)
  • search - Search term
  • page - Page number for pagination
  • perPage - Items per page

Read page

Get full content of a specific page including meta data and builder information.

GET /pages/{id}

Create page duplicate

Create a duplicate of an existing page for safe editing.

POST /pages/{id}/duplicate

Always use this before making changes to an original page. Edit the duplicate, then approve in WordPress admin (Respira → Approve Edits).

Update page

Update a page. Respira automatically creates a duplicate for safety.

PUT /pages/{id}

Body parameters:

  • title - New page title
  • content - New page content (HTML)
  • status - Page status (publish, draft, pending)
  • meta - Post meta data

Delete page

Delete a page. Only works on Respira-created duplicates by default.

DELETE /pages/{id}

Posts

List posts

List all blog posts with optional filtering.

GET /posts

Read post

Get full content of a specific post.

GET /posts/{id}

Create post duplicate

Create a duplicate of an existing post for safe editing.

POST /posts/{id}/duplicate

Update post

Update a post. Respira automatically creates a duplicate for safety.

PUT /posts/{id}

Delete post

Delete a post. Only works on Respira-created duplicates by default.

DELETE /posts/{id}

Custom Post Types

List post types

List all registered post types.

GET /post-types

Get post type

Get post type details.

GET /post-types/{type}

List custom posts

List posts of a custom post type.

GET /post-types/{type}/posts

Get custom post

Get custom post details.

GET /post-types/{type}/posts/{id}

Create custom post

Create a new custom post.

POST /post-types/{type}/posts

Update custom post

Update a custom post.

PUT /post-types/{type}/posts/{id}

Delete custom post

Delete a custom post.

DELETE /post-types/{type}/posts/{id}

Page Builder Tools

Extract builder content

Extract structured content from a page builder (Divi, Elementor, Bricks, etc.).

GET /builder/{builder}/pages/{id}/content

Inject builder content

Inject structured content into a page builder.

POST /builder/{builder}/pages/{id}/content

Update module

Update a specific module within a page builder page. Supports finding modules by admin_label, path, or type.

PUT /builder/{builder}/pages/{id}/module

Body parameters:

  • moduleIdentifier - Object with admin_label, path, or type
  • updates - Object with content and/or attributes

Media

List media

List all media files (images, videos, etc.).

GET /media

Get media

Get single media item details.

GET /media/{id}

Upload media

Upload a media file to WordPress.

POST /media

Body parameters:

  • file - File content as base64 string, URL, or file path
  • filename - Filename for the uploaded file
  • mimeType - MIME type (e.g., image/jpeg)
  • alt - Alt text for images
  • title - Media title
  • caption - Media caption

Update media

Update media metadata (title, alt text, caption).

PUT /media/{id}

Delete media

Delete a media file.

DELETE /media/{id}

List menus

List all navigation menus.

GET /menus

Get menu

Get menu with all items and hierarchy.

GET /menus/{id}

Get menu locations

Get all registered menu locations.

GET /menus/locations

Create menu

Create a new navigation menu.

POST /menus

Update menu

Update a menu.

PUT /menus/{id}

Delete menu

Delete a menu.

DELETE /menus/{id}

Create menu item

Add an item to a menu.

POST /menus/{id}/items

Update menu item

Update a menu item.

PUT /menus/{id}/items/{item_id}

Delete menu item

Delete a menu item.

DELETE /menus/{id}/items/{item_id}

Assign menu location

Assign a menu to a theme location.

POST /menus/{id}/location

Taxonomies

List taxonomies

List all registered taxonomies.

GET /taxonomies

Get taxonomy

Get taxonomy details.

GET /taxonomies/{taxonomy}

List terms

List terms in a taxonomy.

GET /taxonomies/{taxonomy}/terms

Get term

Get term details.

GET /taxonomies/{taxonomy}/terms/{id}

Create term

Create a new term.

POST /taxonomies/{taxonomy}/terms

Update term

Update a term.

PUT /taxonomies/{taxonomy}/terms/{id}

Delete term

Delete a term.

DELETE /taxonomies/{taxonomy}/terms/{id}

Users

List users

List all users with optional filtering.

GET /users

Get user

Get user details by ID.

GET /users/{id}

Create user

Create a new user.

POST /users

Update user

Update user information.

PUT /users/{id}

Delete user

Delete a user.

DELETE /users/{id}

Comments

List comments

List all comments with optional filtering.

GET /comments

Get comment

Get comment details.

GET /comments/{id}

Create comment

Create a new comment.

POST /comments

Update comment

Update a comment.

PUT /comments/{id}

Delete comment

Delete a comment.

DELETE /comments/{id}

Options

List options

List WordPress options (with optional search filter).

GET /options

Get option

Get option value by name.

GET /options/{option}

Update option

Update an option value.

PUT /options/{option}

Delete option

Delete an option.

DELETE /options/{option}

Performance Analysis

Analyze performance

Analyze page performance including load time, images, CSS/JS, caching, and plugin impact.

GET /analyze/performance/{page_id}

Get Core Web Vitals

Get Core Web Vitals metrics (LCP, FID, CLS) for a page.

GET /analyze/core-web-vitals/{page_id}

Analyze images

Analyze image optimization opportunities including missing alt text and large files.

GET /analyze/images/{page_id}

SEO Analysis

Analyze SEO

Comprehensive SEO analysis including meta tags, headings, image alt text, internal linking, and schema markup.

GET /analyze/seo/{page_id}

Check SEO issues

Quick check for common SEO issues with recommendations.

GET /analyze/seo-issues/{page_id}

Analyze readability

Analyze content readability including Flesch Reading Ease score and paragraph structure.

GET /analyze/readability/{page_id}

AI Engine Optimization (AEO)

Analyze AEO

Analyze content for AI search engine optimization (Perplexity, ChatGPT). Checks structured data, content clarity, and semantic HTML.

GET /analyze/aeo/{page_id}

Check structured data

Check schema markup and structured data (JSON-LD, microdata) for AI parsing. Since plugin 9.1.11 the answer lists every JSON-LD block with its values and the plugin that printed it.

GET /analyze/structured-data/{page_id}

Query parameters:

  • contains - Optional. Keep only the JSON-LD blocks whose text contains this

See wordpress_check_structured_data.

Find in page

Find text in the published HTML of a page, head included, and name the snippet or setting on the site that holds it. Read only. Plugin 9.1.11 or newer.

GET /analyze/find-in-page

Query parameters:

  • post_id - Page or post ID. Give this or url
  • url - Address on the same site. Give this or post_id
  • contains - Text to find. Required unless kind is jsonld
  • kind - any (default), head or jsonld
  • limit - Most matches to return, default 8, at most 20

See respira_find_in_page.

Security

Validate security

Validate content for security issues before saving.

POST /security/validate

Plugin Management (Experimental)

Plugin management is experimental and disabled by default. Enable in Respira settings before use.

List plugins

List all installed plugins with status and update availability.

GET /plugins

Install plugin

Install a plugin from WordPress.org or ZIP URL.

POST /plugins/install

Activate plugin

Activate a plugin.

POST /plugins/{slug}/activate

Deactivate plugin

Deactivate a plugin.

POST /plugins/{slug}/deactivate

Update plugin

Update a plugin to latest version.

POST /plugins/{slug}/update

Delete plugin

Delete a plugin (must be deactivated first).

DELETE /plugins/{slug}

Multi-Site

Switch site

Switch to a different WordPress site (for multi-site setups).

POST /sites/switch

Response Format

All responses follow this structure:

Success:

{
  "success": true,
  "data": { ... }
}

Error:

{
  "success": false,
  "message": "Error message"
}
Was this page helpful?