Skip to content

Publish a full OpenAPI spec for REST API v2 - #108

Merged
bkatusic merged 6 commits into
mainfrom
docs/openapi-spec
Aug 3, 2026
Merged

Publish a full OpenAPI spec for REST API v2#108
bkatusic merged 6 commits into
mainfrom
docs/openapi-spec

Conversation

@dennisdornon

@dennisdornon dennisdornon commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

A customer asked for a permalink to clean OpenAPI YAML their software can ingest
(Intercom, 2026-08-01). The closest thing we had was the CustomGPT schema page, which is
YAML inside an MDX fence and trimmed to about 30 operations to fit CustomGPT's cap. This
PR adds the real thing.

What changed

  • api-reference/openapi.yaml: complete OpenAPI 3.1.0 description of REST API v2.
    172 paths, 270 operations, 28 component schemas. Built from three sources: the live
    /wp-json/mainwp/v2/ route index of a testbed Dashboard, the v2 controllers in
    mainwp-6 (params, enums, response envelopes), and the 15 pages under
    api-reference/rest-api/ as the coverage checklist. info.version is 6.1.3, the
    Dashboard version the spec was written against.
  • api-reference/rest-api/overview.mdx: new OpenAPI Specification section with the raw
    GitHub permalink, plus a What You'll Learn bullet and a Related Resources entry, so
    the file is discoverable from the page integrators read.
  • advanced/api/customgpt-schema-for-mainwp-rest-api-v2.mdx: the NOTE now says the
    CustomGPT schema is a trimmed subset and links the full spec.

Route count reconciliation

The live index reports 165 registered routes. WordPress registers separate regex
variants for numeric-id and domain forms of the same path, so those merge to 162
canonical paths; dropping the namespace root leaves 161. Four extension groups
documented in extensions.mdx (SSL Monitor, Domain Monitor, Lighthouse, Pro Reports)
were not installed on the testbed, adding 11 paths the index could not show. 161 + 11 =
172 spec paths. Extension-gated paths carry x-requires-extension.

What to look at

  • The batch request bodies. Codex review found the update item schemas did not require
    the record id and the global batch create schemas diverged from their single-route
    counterparts; both are fixed with shared component schemas (5af452a). The global
    /batch updates group is documented as non-functional because the updates controller
    has no create_item(); that is a product bug, reported separately, not a spec error.
  • The three sites write-only fields (http_user, http_pass, uniqueid) are marked
    writeOnly on purpose; the controller strips them from responses.

Verification

  • npx @redocly/cli lint: 0 errors, 0 warnings. mint broken-links: clean.
  • Coverage script confirms every live route and every endpoint documented in the 15
    MDX pages appears in the spec with its registered methods.
  • Three endpoints spot-checked against controller source: monitors heartbeat, costs
    add, pages create.
  • Reviewed by Codex (three rounds, final APPROVED) and CodeRabbit (three passes, final
    clean). Review fixes landed as their own commits: batch schema corrections (5af452a)
    and documented 400 responses plus a per-monitor description fix (cdb9897).
  • After merge, confirm
    https://github.com/ghraw/mainwp/docs/main/api-reference/openapi.yaml
    parses in a validator. That URL only exists once this lands on main.

Out of scope

Wiring the spec into docs.json so Mintlify generates reference pages. The 15
hand-written endpoint pages are unchanged.

Summary by CodeRabbit

  • New Features

    • Added a complete OpenAPI 3.1 reference for the REST API, covering core resources, extension routes, authentication, errors, requests, responses, and background jobs.
    • Documented available schemas and endpoint operations for sites, clients, updates, posts, settings, monitoring, and more.
  • Documentation

    • Added guidance for accessing and using the full OpenAPI specification.
    • Clarified that the CustomGPT schema is a trimmed selection and linked to the complete API reference.

172 paths / 270 operations generated from the live route index, the v2
controllers, and the docs coverage checklist; CustomGPT page now links the
full spec as the canonical machine-readable description.
Batch update items now require the record id, global and controller batch
create items share the single-route input schemas, and the global batch
updates group is documented as non-functional (updates controller has no
create_item).
Per-monitor active description no longer claims global scope; documented
400 responses on costs add/edit (no target) and per-site update (suspended
site), only where the controllers really throw them.
@mintlify

mintlify Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
mainwp 🟢 Ready View Preview Aug 3, 2026, 3:53 PM

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • api-reference/openapi.yaml
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2c272118-68dc-4ff7-8a92-8f23a868ae9e

📥 Commits

Reviewing files that changed from the base of the PR and between cdb9897 and c565f33.

📒 Files selected for processing (1)
  • api-reference/openapi.yaml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR adds a complete OpenAPI 3.1 reference for MainWP Dashboard REST API v2. It documents core and extension endpoints, reusable schemas, authentication, errors, queued jobs, and links to the specification from API documentation.

Changes

REST API v2 reference

Layer / File(s) Summary
API metadata and reusable contracts
api-reference/openapi.yaml
The specification defines API metadata, bearer authentication, tags, shared response models, request inputs, validation fields, and queued-operation schemas.
Core resource and batch endpoints
api-reference/openapi.yaml
The specification adds batch operations and endpoints for clients, comments, costs, monitors, pages, and posts.
Dashboard and extension endpoints
api-reference/openapi.yaml
The specification adds API-key, settings, site, tag, time-tracking, update, user, Domain Monitor, Lighthouse, Pro Reports, and SSL Monitor routes.
OpenAPI documentation references
api-reference/rest-api/overview.mdx, advanced/api/customgpt-schema-for-mainwp-rest-api-v2.mdx
The documentation links to the complete specification and identifies the CustomGPT schema as a subset of the available operations.

Estimated code review effort: 5 (Critical) | ~90+ minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: publishing a full OpenAPI specification for REST API v2.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/openapi-spec

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
api-reference/openapi.yaml (2)

2872-2874: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add items to the untyped arrays.

expected_status declares type: array with no items. The same gap exists for sync_data (Lines 5065-5067, 5168-5170), mainwp_widgets (Lines 6232-6234), automatic_daily_update (Lines 6133-6135), trans_automatic_daily_update (Lines 6262-6264), mainwp_uptime_monitoring_up_status_codes (Lines 6523-6525), and post_gallery_images (Lines 4259-4261).

OpenAPI 3.1 accepts this, so the document stays valid. Code generators and try-it consoles then treat each field as an array of any type and show no usable example.

♻️ Proposed change for `expected_status`
                 expected_status:
                   type: array
+                  items:
+                    type: integer
                   description: Expected HTTP status codes.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api-reference/openapi.yaml` around lines 2872 - 2874, Update the array
schemas for expected_status, sync_data, mainwp_widgets, automatic_daily_update,
trans_automatic_daily_update, mainwp_uptime_monitoring_up_status_codes, and
post_gallery_images to declare appropriate items schemas, preserving each
field’s intended element type so generators and consoles can provide usable
examples.

135-234: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the repeated request bodies into components.requestBodies.

post, put, and patch on this path carry three byte-identical copies of the same inline schema. The same triplication repeats on /clients/batch, /costs/batch, /sites/batch, and /tags/batch. A later edit to one method leaves the other two stale, and the published reference then shows two different contracts for one route.

Define each body once under components.requestBodies and reference it from all three methods.

♻️ Proposed refactor
       requestBody:
-        required: true
-        content:
-          application/json:
-            schema:
-              type: object
-              properties:
-                sites:
-                  ...
+        $ref: '`#/components/requestBodies/GlobalBatchRequest`'

Then add the shared definition under components:

components:
  requestBodies:
    GlobalBatchRequest:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              sites: {}   # move the existing definition here unchanged
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api-reference/openapi.yaml` around lines 135 - 234, Extract the repeated
inline batch request schema from the post, put, and patch operations into a
shared components.requestBodies.GlobalBatchRequest definition, preserving the
existing schema unchanged. Replace each operation’s requestBody with a reference
to this shared request body, and apply the same deduplication to the
corresponding batch endpoints for clients, costs, sites, and tags.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@api-reference/openapi.yaml`:
- Around line 2869-2871: Update the descriptions for the `active` fields to say
“Enable or disable monitoring globally” instead of “Active or disable monitoring
globally” at this occurrence and every other listed occurrence, including the
entries near lines 2941, 4740, 4832, 4880, 6500, and 6569.
- Line 13039: Update all four x-requires-extension values in the OpenAPI
definition to use the consistent “MainWP Lighthouse” product name, replacing any
bare “Lighthouse” values while leaving unrelated extension values unchanged.

---

Nitpick comments:
In `@api-reference/openapi.yaml`:
- Around line 2872-2874: Update the array schemas for expected_status,
sync_data, mainwp_widgets, automatic_daily_update, trans_automatic_daily_update,
mainwp_uptime_monitoring_up_status_codes, and post_gallery_images to declare
appropriate items schemas, preserving each field’s intended element type so
generators and consoles can provide usable examples.
- Around line 135-234: Extract the repeated inline batch request schema from the
post, put, and patch operations into a shared
components.requestBodies.GlobalBatchRequest definition, preserving the existing
schema unchanged. Replace each operation’s requestBody with a reference to this
shared request body, and apply the same deduplication to the corresponding batch
endpoints for clients, costs, sites, and tags.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a434faf2-747e-4124-a9cd-064737a6d8db

📥 Commits

Reviewing files that changed from the base of the PR and between bd5fa44 and cdb9897.

📒 Files selected for processing (3)
  • advanced/api/customgpt-schema-for-mainwp-rest-api-v2.mdx
  • api-reference/openapi.yaml
  • api-reference/rest-api/overview.mdx

Comment thread api-reference/openapi.yaml Outdated
Comment thread api-reference/openapi.yaml Outdated
Fix the Enable/disable verb error in toggle descriptions, prefix the
Lighthouse x-requires-extension values, and type the array fields whose
element shape the controllers prove; sync_data and mainwp_widgets become
objects because their validators reject JSON arrays outright.
@dennisdornon

Copy link
Copy Markdown
Contributor Author

@coderabbitai Dispositions for the four findings, fixes in 1a9dd20:

  1. "Active or disable" verb error: fixed everywhere it appeared (9 occurrences). It is a registered controller string, so the fix is applied wherever the generator copies a registered description.
  2. Lighthouse x-requires-extension values: fixed to MainWP Lighthouse, matching the other extension values and the plugin header. The OpenAPI tag stays "Lighthouse" to match the docs page title.
  3. Untyped arrays: typed where the controllers prove the element type. Two of the suggestions turned out wrong in the code's favor: post_gallery_images items are objects ({id, alt, caption, description, src, title}), and sync_data / mainwp_widgets are objects with 0/1 values, because their sanitizers iterate string keys and a JSON array can never validate. expected_status stays untyped: its sanitizer treats it as a comma separated string and the monitor settings schema declares type: ["string"], so an items type would be fiction; the description now states the accepted form. automatic_daily_update / trans_automatic_daily_update are skipped because their registration is self-contradictory (array type, 0/1 enum validation, int consumption); that is an upstream plugin bug we are tracking separately.
  4. Extracting the triplicated batch request bodies into components.requestBodies: not doing this one. The file is generated, and all three methods of each batch route emit from a single data source in the generator, so the drift hazard the suggestion protects against cannot occur. The item schemas are already shared components.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show --stat --oneline 1a9dd20
git show --format=fuller --find-renames --find-copies -- api-reference/openapi.yaml 1a9dd20

printf '\n--- Matching documentation and generator references ---\n'
rg -n -i -C 2 'generated|generator|active or disable|MainWP Lighthouse|post_gallery_images|sync_data|mainwp_widgets|expected_status|automatic_daily_update|trans_automatic_daily_update|requestBodies' \
  api-reference README.md .github 2>/dev/null || true

Length of output: 25204


@dennisdornon Confirmed for commit 1a9dd20:

  1. The verb correction is applied to all affected descriptions.
  2. All Lighthouse paths now use x-requires-extension: MainWP Lighthouse. The Lighthouse tag remains suitable.
  3. The schemas for post_gallery_images, sync_data, and mainwp_widgets now describe their supported values correctly.
  4. I withdraw the components.requestBodies recommendation. A shared generator data source prevents the stated drift risk.

One issue remains for expected_status. The description now correctly says that the API accepts a comma-separated string, but the OpenAPI schema still declares type: array at Lines 2872, 2942, 3336, and 3418. Change these declarations to type: string to match the actual request format. Do not add items to this field.

🐇🔎


✏️ Learnings added
Learnt from: dennisdornon
URL: https://github.com/mainwp/docs/pull/108

Timestamp: 2026-08-03T16:05:51.327Z
Learning: `api-reference/openapi.yaml` is generated. For batch endpoints, the generator emits the request bodies for all HTTP methods from one data source, and the batch item schemas are shared OpenAPI components. Do not recommend extracting these request bodies into `components.requestBodies` only to prevent method-to-method drift.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

An array payload degrades to the string "Array" in the sanitizer and can
never validate; the route's own settings schema already declares string.
@dennisdornon

Copy link
Copy Markdown
Contributor Author

@coderabbitai expected_status is now declared type: string at all four sites (c565f33), no items. Verified in the monitors controller before changing: both the sanitizer and validator open with sanitize_text_field( wp_unslash( $value ) ), so an array payload degrades to the string "Array" and fails with "Invalid HTTP status code: 0"; the route's own settings schema at :2209 already declares string. The registered type: array in the plugin is itself a bug, tracked in our upstream fix list.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show --format=fuller --find-renames --find-copies c565f33 -- api-reference/openapi.yaml

printf '\n--- Current expected_status declarations ---\n'
rg -n -A8 -B3 '^\s*expected_status:' api-reference/openapi.yaml

printf '\n--- Count and schema-shape checks ---\n'
python3 - <<'PY'
from pathlib import Path
import re

text = Path("api-reference/openapi.yaml").read_text()
blocks = list(re.finditer(r'(?ms)^(\s*)expected_status:\n(.*?)(?=^\1\S|\Z)', text))
print(f"expected_status blocks: {len(blocks)}")
for index, block in enumerate(blocks, 1):
    body = block.group(0)
    print(f"\nBlock {index}:")
    print("  has type: string:", bool(re.search(r'(?m)^\s+type:\s*string\s*$', body)))
    print("  has items:", bool(re.search(r'(?m)^\s+items:\s*$', body)))
PY

Length of output: 6154


@dennisdornon Confirmed. Commit c565f33 updates all four expected_status schemas to type: string. None of the four schemas has an items property. The descriptions correctly specify the comma-separated status-code format.

You are interacting with an AI system.

@bkatusic
bkatusic merged commit 773175d into main Aug 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants