# Managing Elevated Product Search with Your AI Agent (agent documentation)

> Machine-readable documentation for AI agents. Human version: https://elevatedextensions.com/documentation/product-search/managing-with-ai-agent/

This is the complete machine-readable reference for the 12 `elevated-product-search/*` abilities in Elevated Product Search. Every schema below is served verbatim from the ability registry (the same schemas the MCP server and the REST surface enforce), and every example is a real captured response.

## Calling conventions

Two equivalent surfaces, one registry:

- **MCP**: connect to `/wp-json/mcp/mcp-adapter-default-server` (MCP Streamable HTTP). Each ability is exposed as an MCP tool with the same name. Pass the input object as the tool arguments.
- **REST**: `/wp-json/wp-abilities/v1/abilities/{ability-name}/run`, authenticated as an administrator (use an application password). The HTTP method is enforced from the ability's annotations:

| Annotations | Method | Where the input goes |
|---|---|---|
| `readonly: true` | GET | `input` query parameter, PHP bracket syntax: `?input[query]=test&input[limit]=5` |
| `destructive: true` and `idempotent: true` | DELETE | `input` query parameter |
| everything else | POST | JSON body: `{"input": { ... }}` |

Each ability section below states its resolved method.

`GET /wp-json/wp-abilities/v1/abilities` lists every ability with its full input and output schema; `GET /wp-json/wp-abilities/v1/abilities/{ability-name}` returns one.

Wrong method:

```json
{
 "status": 405,
 "data": {
  "code": "rest_ability_invalid_method",
  "message": "Read-only abilities require GET method.",
  "data": {
   "status": 405
  }
 }
}
```

The other two rejection messages, from the same rule: `"Abilities that perform destructive actions require DELETE method."` and `"Abilities that perform updates require POST method."`

Unauthenticated:

```json
{
 "status": 401,
 "data": {
  "code": "rest_ability_cannot_execute",
  "message": "Sorry, you are not allowed to execute this ability.",
  "data": {
   "status": 401
  }
 }
}
```

Input is validated against the schema before any handler runs. Unknown keys are rejected, not ignored, and every rejection names the valid values (see the error catalog at the end).

**Agent access switch.** The site owner can turn agent access off (Elevated Product Search settings, stored as option `elevated_product_search_agent_access` = `"no"`). While off, the abilities are not registered and every call fails with:

```json
{
 "status": 404,
 "error": {
  "code": "rest_ability_not_found",
  "message": "Ability not found."
 }
}
```

Only a human can switch access back on; do not retry, ask the site owner.

## The settings object

One settings object backs `get-settings` and `update-settings`. It has 163 properties. A `get-settings` response always contains the 99 required keys; the 64 per-side border, radius, and padding override keys appear only when they are set. In an `update-settings` patch those same 64 keys additionally accept `null`, which clears the per-side override so the shorthand key applies again. The 64 keys:

`iconPaddingBottom, iconPaddingLeft, iconPaddingRight, iconPaddingTop, inputBorderRadiusBL, inputBorderRadiusBR, inputBorderRadiusTL, inputBorderRadiusTR, inputBorderWeightBottom, inputBorderWeightLeft, inputBorderWeightRight, inputBorderWeightTop, inputPaddingBottom, inputPaddingLeft, inputPaddingRight, inputPaddingTop, previewImageBorderRadiusBL, previewImageBorderRadiusBR, previewImageBorderRadiusTL, previewImageBorderRadiusTR, previewImageBorderWidthBottom, previewImageBorderWidthLeft, previewImageBorderWidthRight, previewImageBorderWidthTop, resultImageBorderRadiusBL, resultImageBorderRadiusBR, resultImageBorderRadiusTL, resultImageBorderRadiusTR, resultImageBorderWidthBottom, resultImageBorderWidthLeft, resultImageBorderWidthRight, resultImageBorderWidthTop, resultItemBorderRadiusBL, resultItemBorderRadiusBR, resultItemBorderRadiusTL, resultItemBorderRadiusTR, resultItemBorderWidthBottom, resultItemBorderWidthLeft, resultItemBorderWidthRight, resultItemBorderWidthTop, resultItemHoverBorderRadiusBL, resultItemHoverBorderRadiusBR, resultItemHoverBorderRadiusTL, resultItemHoverBorderRadiusTR, resultItemHoverBorderWidthBottom, resultItemHoverBorderWidthLeft, resultItemHoverBorderWidthRight, resultItemHoverBorderWidthTop, resultsAreaPaddingBottom, resultsAreaPaddingLeft, resultsAreaPaddingRight, resultsAreaPaddingTop, resultsBorderRadiusBL, resultsBorderRadiusBR, resultsBorderRadiusTL, resultsBorderRadiusTR, resultsBorderWidthBottom, resultsBorderWidthLeft, resultsBorderWidthRight, resultsBorderWidthTop, resultsListPaddingBottom, resultsListPaddingLeft, resultsListPaddingRight, resultsListPaddingTop`

The schema (served by the registry; in update patches, each of the 64 keys above additionally allows type `null`):

```json
{
 "type": "object",
 "properties": {
  "minChars": {
   "type": "integer",
   "minimum": 1,
   "maximum": 5
  },
  "maxFormWidth": {
   "type": "string"
  },
  "breakpoint": {
   "type": "string"
  },
  "showSubmitButton": {
   "type": "boolean"
  },
  "layout": {
   "type": "string",
   "enum": [
    "search-bar",
    "icon-mobile",
    "icon-only"
   ]
  },
  "searchButtonColor": {
   "type": "string"
  },
  "searchButtonTextColor": {
   "type": "string"
  },
  "searchButtonTextSize": {
   "type": "integer"
  },
  "searchButtonBorderRadius": {
   "type": "integer"
  },
  "searchButtonText": {
   "type": "string"
  },
  "inputBackgroundColor": {
   "type": "string"
  },
  "inputTextColor": {
   "type": "string"
  },
  "inputBorderColor": {
   "type": "string"
  },
  "showBorderStyles": {
   "type": "boolean"
  },
  "inputBorderWeight": {
   "type": "integer"
  },
  "inputBorderWeightTop": {
   "type": "integer"
  },
  "inputBorderWeightRight": {
   "type": "integer"
  },
  "inputBorderWeightBottom": {
   "type": "integer"
  },
  "inputBorderWeightLeft": {
   "type": "integer"
  },
  "inputBorderRadius": {
   "type": "integer"
  },
  "inputBorderRadiusTL": {
   "type": "integer"
  },
  "inputBorderRadiusTR": {
   "type": "integer"
  },
  "inputBorderRadiusBR": {
   "type": "integer"
  },
  "inputBorderRadiusBL": {
   "type": "integer"
  },
  "maxResults": {
   "type": "integer",
   "minimum": 1,
   "maximum": 20
  },
  "noResultsLabel": {
   "type": "string"
  },
  "showProductImages": {
   "type": "boolean"
  },
  "showProductPrice": {
   "type": "boolean"
  },
  "showDescription": {
   "type": "boolean"
  },
  "showSKU": {
   "type": "boolean"
  },
  "resultTitleSize": {
   "type": "integer"
  },
  "resultTitleColor": {
   "type": "string"
  },
  "resultTitleHoverColor": {
   "type": "string"
  },
  "resultPriceColor": {
   "type": "string"
  },
  "resultPriceSize": {
   "type": "integer"
  },
  "resultPriceHoverColor": {
   "type": "string"
  },
  "resultSkuColor": {
   "type": "string"
  },
  "resultSkuSize": {
   "type": "integer"
  },
  "resultSkuHoverColor": {
   "type": "string"
  },
  "resultDescriptionColor": {
   "type": "string"
  },
  "resultDescriptionSize": {
   "type": "integer"
  },
  "resultDescriptionHoverColor": {
   "type": "string"
  },
  "resultItemBackground": {
   "type": "string"
  },
  "resultItemBorder": {
   "type": "boolean"
  },
  "resultItemBorderColor": {
   "type": "string"
  },
  "resultItemBorderWidth": {
   "type": "integer"
  },
  "resultItemBorderWidthTop": {
   "type": "integer"
  },
  "resultItemBorderWidthRight": {
   "type": "integer"
  },
  "resultItemBorderWidthBottom": {
   "type": "integer"
  },
  "resultItemBorderWidthLeft": {
   "type": "integer"
  },
  "resultItemBorderRadius": {
   "type": "integer"
  },
  "resultItemBorderRadiusTL": {
   "type": "integer"
  },
  "resultItemBorderRadiusTR": {
   "type": "integer"
  },
  "resultItemBorderRadiusBR": {
   "type": "integer"
  },
  "resultItemBorderRadiusBL": {
   "type": "integer"
  },
  "resultItemBorderStyle": {
   "type": "string"
  },
  "resultItemHoverBorder": {
   "type": "boolean"
  },
  "resultItemHoverBorderColor": {
   "type": "string"
  },
  "resultItemHoverBorderWidth": {
   "type": "integer"
  },
  "resultItemHoverBorderWidthTop": {
   "type": "integer"
  },
  "resultItemHoverBorderWidthRight": {
   "type": "integer"
  },
  "resultItemHoverBorderWidthBottom": {
   "type": "integer"
  },
  "resultItemHoverBorderWidthLeft": {
   "type": "integer"
  },
  "resultItemHoverBorderRadius": {
   "type": "integer"
  },
  "resultItemHoverBorderRadiusTL": {
   "type": "integer"
  },
  "resultItemHoverBorderRadiusTR": {
   "type": "integer"
  },
  "resultItemHoverBorderRadiusBR": {
   "type": "integer"
  },
  "resultItemHoverBorderRadiusBL": {
   "type": "integer"
  },
  "resultImageBorder": {
   "type": "boolean"
  },
  "resultImageBorderColor": {
   "type": "string"
  },
  "resultImageBorderWidth": {
   "type": "integer"
  },
  "resultImageBorderWidthTop": {
   "type": "integer"
  },
  "resultImageBorderWidthRight": {
   "type": "integer"
  },
  "resultImageBorderWidthBottom": {
   "type": "integer"
  },
  "resultImageBorderWidthLeft": {
   "type": "integer"
  },
  "resultImageBorderRadius": {
   "type": "integer"
  },
  "resultImageBorderRadiusTL": {
   "type": "integer"
  },
  "resultImageBorderRadiusTR": {
   "type": "integer"
  },
  "resultImageBorderRadiusBR": {
   "type": "integer"
  },
  "resultImageBorderRadiusBL": {
   "type": "integer"
  },
  "resultsSectionLabelsColor": {
   "type": "string"
  },
  "resultsSectionLabelsTextSize": {
   "type": "integer"
  },
  "showMoreResultsButton": {
   "type": "boolean"
  },
  "moreResultsLabel": {
   "type": "string"
  },
  "moreResultsBgColor": {
   "type": "string"
  },
  "moreResultsTextColor": {
   "type": "string"
  },
  "moreResultsTextSize": {
   "type": "integer"
  },
  "resultsAreaPadding": {
   "type": "string"
  },
  "resultsAreaPaddingTop": {
   "type": "integer"
  },
  "resultsAreaPaddingRight": {
   "type": "integer"
  },
  "resultsAreaPaddingBottom": {
   "type": "integer"
  },
  "resultsAreaPaddingLeft": {
   "type": "integer"
  },
  "resultsListPadding": {
   "type": "string"
  },
  "resultsListPaddingTop": {
   "type": "integer"
  },
  "resultsListPaddingRight": {
   "type": "integer"
  },
  "resultsListPaddingBottom": {
   "type": "integer"
  },
  "resultsListPaddingLeft": {
   "type": "integer"
  },
  "resultItemGap": {
   "type": "integer"
  },
  "showResultsBorderControls": {
   "type": "boolean"
  },
  "resultsBorderColor": {
   "type": "string"
  },
  "resultsBorderWidth": {
   "type": "integer"
  },
  "resultsBorderWidthTop": {
   "type": "integer"
  },
  "resultsBorderWidthRight": {
   "type": "integer"
  },
  "resultsBorderWidthBottom": {
   "type": "integer"
  },
  "resultsBorderWidthLeft": {
   "type": "integer"
  },
  "resultsBorderRadius": {
   "type": "integer"
  },
  "resultsBorderRadiusTL": {
   "type": "integer"
  },
  "resultsBorderRadiusTR": {
   "type": "integer"
  },
  "resultsBorderRadiusBR": {
   "type": "integer"
  },
  "resultsBorderRadiusBL": {
   "type": "integer"
  },
  "showProductPreview": {
   "type": "boolean"
  },
  "resultsBackground": {
   "type": "string"
  },
  "resultHoverBackground": {
   "type": "string"
  },
  "previewImageBorderRadius": {
   "type": "integer"
  },
  "previewImageBorderRadiusTL": {
   "type": "integer"
  },
  "previewImageBorderRadiusTR": {
   "type": "integer"
  },
  "previewImageBorderRadiusBR": {
   "type": "integer"
  },
  "previewImageBorderRadiusBL": {
   "type": "integer"
  },
  "previewImageBorder": {
   "type": "boolean"
  },
  "previewImageBorderColor": {
   "type": "string"
  },
  "previewImageBorderWidth": {
   "type": "integer"
  },
  "previewImageBorderWidthTop": {
   "type": "integer"
  },
  "previewImageBorderWidthRight": {
   "type": "integer"
  },
  "previewImageBorderWidthBottom": {
   "type": "integer"
  },
  "previewImageBorderWidthLeft": {
   "type": "integer"
  },
  "previewButtonBackground": {
   "type": "string"
  },
  "previewButtonTextColor": {
   "type": "string"
  },
  "previewButtonTextSize": {
   "type": "integer"
  },
  "previewButtonBorderRadius": {
   "type": "integer"
  },
  "previewHoverTextColor": {
   "type": "string"
  },
  "previewTextColor": {
   "type": "string"
  },
  "inputPaddingX": {
   "type": "integer"
  },
  "inputPaddingY": {
   "type": "integer"
  },
  "inputPaddingTop": {
   "type": "integer"
  },
  "inputPaddingRight": {
   "type": "integer"
  },
  "inputPaddingBottom": {
   "type": "integer"
  },
  "inputPaddingLeft": {
   "type": "integer"
  },
  "iconPaddingX": {
   "type": "integer"
  },
  "iconPaddingY": {
   "type": "integer"
  },
  "iconPaddingTop": {
   "type": "integer"
  },
  "iconPaddingRight": {
   "type": "integer"
  },
  "iconPaddingBottom": {
   "type": "integer"
  },
  "iconPaddingLeft": {
   "type": "integer"
  },
  "iconColor": {
   "type": "string"
  },
  "iconSize": {
   "type": "integer"
  },
  "inputFontSize": {
   "type": "integer"
  },
  "searchInDescription": {
   "type": "boolean"
  },
  "searchInShortDescription": {
   "type": "boolean"
  },
  "searchInSKUs": {
   "type": "boolean"
  },
  "searchInAttributes": {
   "type": "boolean"
  },
  "searchInCategories": {
   "type": "boolean"
  },
  "searchInTags": {
   "type": "boolean"
  },
  "searchInCustomFields": {
   "type": "array",
   "description": "Product meta keys to include in the search scope. Use list-searchable-custom-fields to discover valid keys.",
   "items": {
    "type": "string"
   }
  },
  "excludeOutOfStock": {
   "type": "boolean"
  },
  "fuzzyMatching": {
   "type": "string",
   "enum": [
    "off",
    "soft",
    "normal",
    "hard"
   ]
  },
  "includeExcludeProducts": {
   "type": "string",
   "enum": [
    "all",
    "include",
    "exclude"
   ]
  },
  "indexSchedule": {
   "type": "boolean"
  },
  "indexInterval": {
   "type": "string",
   "enum": [
    "daily",
    "weekly",
    "monthly"
   ]
  },
  "indexTime": {
   "type": "string"
  },
  "filters": {
   "type": "array",
   "description": "Category and tag filters applied when includeExcludeProducts is include or exclude. Ignored when it is all.",
   "items": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "categories",
       "tags"
      ],
      "description": "Which taxonomy the value names."
     },
     "value": {
      "type": "string",
      "description": "The term slug, exactly as find-filter-terms reports it in its slug field. Term ids are not accepted and match nothing."
     }
    },
    "required": [
     "type",
     "value"
    ],
    "additionalProperties": false
   }
  },
  "descriptionType": {
   "type": "string",
   "enum": [
    "none",
    "short",
    "long"
   ]
  },
  "descriptionWordLimit": {
   "type": "integer",
   "minimum": 5,
   "maximum": 100
  },
  "enableDebugMode": {
   "type": "boolean"
  }
 },
 "required": [
  "minChars",
  "maxFormWidth",
  "breakpoint",
  "showSubmitButton",
  "layout",
  "searchButtonColor",
  "searchButtonTextColor",
  "searchButtonTextSize",
  "searchButtonBorderRadius",
  "searchButtonText",
  "inputBackgroundColor",
  "inputTextColor",
  "inputBorderColor",
  "showBorderStyles",
  "inputBorderWeight",
  "inputBorderRadius",
  "maxResults",
  "noResultsLabel",
  "showProductImages",
  "showProductPrice",
  "showDescription",
  "showSKU",
  "resultTitleSize",
  "resultTitleColor",
  "resultTitleHoverColor",
  "resultPriceColor",
  "resultPriceSize",
  "resultPriceHoverColor",
  "resultSkuColor",
  "resultSkuSize",
  "resultSkuHoverColor",
  "resultDescriptionColor",
  "resultDescriptionSize",
  "resultDescriptionHoverColor",
  "resultItemBackground",
  "resultItemBorder",
  "resultItemBorderColor",
  "resultItemBorderWidth",
  "resultItemBorderRadius",
  "resultItemBorderStyle",
  "resultItemHoverBorder",
  "resultItemHoverBorderColor",
  "resultItemHoverBorderWidth",
  "resultItemHoverBorderRadius",
  "resultImageBorder",
  "resultImageBorderColor",
  "resultImageBorderWidth",
  "resultImageBorderRadius",
  "resultsSectionLabelsColor",
  "resultsSectionLabelsTextSize",
  "showMoreResultsButton",
  "moreResultsLabel",
  "moreResultsBgColor",
  "moreResultsTextColor",
  "moreResultsTextSize",
  "resultsAreaPadding",
  "resultsListPadding",
  "resultItemGap",
  "showResultsBorderControls",
  "resultsBorderColor",
  "resultsBorderWidth",
  "resultsBorderRadius",
  "showProductPreview",
  "resultsBackground",
  "resultHoverBackground",
  "previewImageBorderRadius",
  "previewImageBorder",
  "previewImageBorderColor",
  "previewImageBorderWidth",
  "previewButtonBackground",
  "previewButtonTextColor",
  "previewButtonTextSize",
  "previewButtonBorderRadius",
  "previewHoverTextColor",
  "previewTextColor",
  "inputPaddingX",
  "inputPaddingY",
  "iconPaddingX",
  "iconPaddingY",
  "iconColor",
  "iconSize",
  "inputFontSize",
  "searchInDescription",
  "searchInShortDescription",
  "searchInSKUs",
  "searchInAttributes",
  "searchInCategories",
  "searchInTags",
  "searchInCustomFields",
  "excludeOutOfStock",
  "fuzzyMatching",
  "includeExcludeProducts",
  "indexSchedule",
  "indexInterval",
  "indexTime",
  "filters",
  "descriptionType",
  "descriptionWordLimit",
  "enableDebugMode"
 ],
 "additionalProperties": false
}
```

## Abilities

### `elevated-product-search/get-settings`

Retrieves the complete Elevated Product Search settings, filled out with the shipped defaults. Annotations: readonly, idempotent. REST method: GET.

The response fills every shipped default, so read it once before patching: it is the authoritative current state.

Input schema:

```json
{
 "type": "object",
 "properties": [],
 "additionalProperties": false,
 "default": {}
}
```

Output schema: the `settings` value is the settings object above.

```json
{
 "type": "object",
 "properties": {
  "settings": "<the 163-property settings object: see The settings object above>"
 },
 "additionalProperties": false,
 "required": [
  "settings"
 ]
}
```

**Example: read the current settings**

Input:

```json
{}
```

Response:

```json
{
 "settings": {
  "minChars": 3,
  "maxFormWidth": "600px",
  "breakpoint": "900px",
  "showSubmitButton": false,
  "layout": "search-bar",
  "searchButtonColor": "hsl(var(--primary))",
  "searchButtonTextColor": "hsl(var(--primary-foreground))",
  "searchButtonTextSize": 14,
  "searchButtonBorderRadius": 8,
  "searchButtonText": "Search",
  "inputBackgroundColor": "rgb(255, 255, 255)",
  "inputTextColor": "hsl(var(--foreground))",
  "inputBorderColor": "#e5e7eb",
  "showBorderStyles": false,
  "inputBorderWeight": 1,
  "inputBorderRadius": 8,
  "maxResults": 6,
  "noResultsLabel": "No results found",
  "inputPaddingX": 12,
  "inputPaddingY": 10,
  "iconPaddingX": 12,
  "iconPaddingY": 12,
  "iconColor": "hsl(var(--muted-foreground))",
  "iconSize": 16,
  "inputFontSize": 14,
  "showProductImages": true,
  "showProductPrice": true,
  "showDescription": false,
  "showSKU": false,
  "resultTitleSize": 16,
  "resultTitleColor": "hsl(var(--foreground))",
  "resultTitleHoverColor": "hsl(var(--foreground))",
  "resultPriceColor": "hsl(var(--foreground))",
  "resultPriceSize": 14,
  "resultPriceHoverColor": "hsl(var(--foreground))",
  "resultSkuColor": "hsl(var(--muted-foreground))",
  "resultSkuSize": 12,
  "resultSkuHoverColor": "hsl(var(--muted-foreground))",
  "resultDescriptionColor": "hsl(var(--muted-foreground))",
  "resultDescriptionSize": 12,
  "resultDescriptionHoverColor": "hsl(var(--muted-foreground))",
  "resultItemBackground": "transparent",
  "resultItemBorder": false,
  "resultItemBorderColor": "hsl(var(--border))",
  "resultItemBorderWidth": 0,
  "resultItemBorderRadius": 8,
  "resultItemBorderStyle": "solid",
  "resultItemHoverBorder": false,
  "resultItemHoverBorderColor": "hsl(var(--border))",
  "resultItemHoverBorderWidth": 0,
  "resultItemHoverBorderRadius": 8,
  "resultImageBorder": false,
  "resultImageBorderColor": "hsl(var(--border))",
  "resultImageBorderWidth": 0,
  "resultImageBorderRadius": 10,
  "resultsSectionLabelsColor": "hsl(var(--foreground))",
  "resultsSectionLabelsTextSize": 14,
  "showMoreResultsButton": true,
  "moreResultsLabel": "See all products...",
  "moreResultsBgColor": "hsl(var(--primary-light, 210 40% 96%))",
  "moreResultsTextColor": "hsl(var(--primary))",
  "moreResultsTextSize": 14,
  "resultsAreaPadding": "14px",
  "resultsListPadding": "0",
  "resultItemGap": 4,
  "showResultsBorderControls": false,
  "resultsBorderColor": "hsl(var(--border))",
  "resultsBorderWidth": 0,
  "resultsBorderRadius": 10,
  "showProductPreview": true,
  "resultsBackground": "rgb(255, 255, 255)",
  "resultHoverBackground": "hsl(210 40% 96.1%)",
  "previewImageBorderRadius": 3,
  "previewImageBorder": false,
  "previewImageBorderColor": "hsl(var(--border))",
  "previewImageBorderWidth": 0,
  "previewButtonBackground": "#0077C2",
  "previewButtonTextColor": "#fff",
  "previewButtonTextSize": 14,
  "previewButtonBorderRadius": 8,
  "previewHoverTextColor": "#ffffff",
  "previewTextColor": "#000000",
  "searchInDescription": false,
  "searchInShortDescription": false,
  "searchInSKUs": false,
  "searchInAttributes": false,
  "searchInCategories": false,
  "searchInTags": false,
  "searchInCustomFields": [],
  "excludeOutOfStock": false,
  "fuzzyMatching": "normal",
  "includeExcludeProducts": "all",
  "indexSchedule": false,
  "indexInterval": "weekly",
  "indexTime": "00:00",
  "filters": [],
  "descriptionType": "long",
  "descriptionWordLimit": 20,
  "enableDebugMode": false
 }
}
```

### `elevated-product-search/update-settings`

Updates Elevated Product Search settings. Changing the search scope schedules an index rebuild. Annotations: write, idempotent. REST method: POST.

Send only the keys you are changing; the patch merges into stored settings and the response returns the complete resulting settings plus `updated_keys` and `deleted_keys`. Changing any of the seven search scope keys (`searchInDescription`, `searchInShortDescription`, `searchInSKUs`, `searchInAttributes`, `searchInCategories`, `searchInTags`, `searchInCustomFields`) triggers an index rebuild, reported as `index_rebuilding: true`. An empty patch is rejected by the handler (`empty_settings_patch`).

Input schema: the `settings` value accepts a partial patch of the settings object above.

```json
{
 "type": "object",
 "properties": {
  "settings": "<partial patch of the settings object above; no key is required; the 64 per-side override keys also accept null>"
 },
 "additionalProperties": false,
 "required": [
  "settings"
 ]
}
```

Output schema: the `settings` value is the settings object above.

```json
{
 "type": "object",
 "properties": {
  "settings": "<the 163-property settings object: see The settings object above>",
  "index_rebuilding": {
   "type": "boolean"
  },
  "updated_keys": {
   "type": "array",
   "items": {
    "type": "string"
   }
  },
  "deleted_keys": {
   "type": "array",
   "items": {
    "type": "string"
   }
  }
 },
 "additionalProperties": false,
 "required": [
  "settings",
  "index_rebuilding",
  "updated_keys",
  "deleted_keys"
 ]
}
```

**Example: change one setting (the settings object in the response is elided here)**

Input:

```json
{
 "settings": {
  "fuzzyMatching": "soft"
 }
}
```

Response:

```json
{
 "settings": "<the full 99-key settings object, elided>",
 "index_rebuilding": false,
 "updated_keys": [
  "fuzzyMatching"
 ],
 "deleted_keys": []
}
```

**Example: a scope change reports the triggered rebuild (settings elided)**

Input:

```json
{
 "settings": {
  "searchInSKUs": true
 }
}
```

Response:

```json
{
 "settings": "<the full 99-key settings object, elided>",
 "index_rebuilding": true,
 "updated_keys": [
  "searchInSKUs"
 ],
 "deleted_keys": []
}
```

**Example: empty patch**

Input:

```json
{
 "settings": {}
}
```

Response:

```json
{
 "error": {
  "code": "empty_settings_patch",
  "message": "The settings patch does not contain any settings to update."
 }
}
```

**Example: out-of-enum value**

Input:

```json
{
 "settings": {
  "fuzzyMatching": "extreme"
 }
}
```

Response:

```json
{
 "error": {
  "code": "ability_invalid_input",
  "message": "Ability \"elevated-product-search/update-settings\" has invalid input. Reason: input[settings][fuzzyMatching] is not one of off, soft, normal, and hard."
 }
}
```

**Example: unknown key (closed schema)**

Input:

```json
{
 "settings": {
  "nope": true
 }
}
```

Response:

```json
{
 "error": {
  "code": "ability_invalid_input",
  "message": "Ability \"elevated-product-search/update-settings\" has invalid input. Reason: nope is not a valid property of Object."
 }
}
```

### `elevated-product-search/reset-settings`

Discards every saved Elevated Product Search setting and restores the shipped defaults. Requires confirmation. Annotations: write, destructive, idempotent. REST method: DELETE.

Input schema:

```json
{
 "type": "object",
 "properties": {
  "confirm": {
   "type": "boolean"
  }
 },
 "additionalProperties": false,
 "required": [
  "confirm"
 ]
}
```

Output schema: the `settings` value is the settings object above.

```json
{
 "type": "object",
 "properties": {
  "settings": "<the 163-property settings object: see The settings object above>",
  "index_rebuilding": {
   "type": "boolean"
  },
  "updated_keys": {
   "type": "array",
   "items": {
    "type": "string"
   }
  },
  "deleted_keys": {
   "type": "array",
   "items": {
    "type": "string"
   }
  }
 },
 "additionalProperties": false,
 "required": [
  "settings",
  "index_rebuilding",
  "updated_keys",
  "deleted_keys"
 ]
}
```

**Example: without confirm (fails before any side effect)**

Input:

```json
{}
```

Response:

```json
{
 "error": {
  "code": "ability_invalid_input",
  "message": "Ability \"elevated-product-search/reset-settings\" has invalid input. Reason: confirm is a required property of input."
 }
}
```

### `elevated-product-search/search-products`

Searches the product index the storefront widget uses, honouring the configured include and exclude filters. Annotations: readonly, idempotent. REST method: GET.

`total` is capped at `limit`; it is not a catalog-wide count. The same query returns `total: 9` unlimited and `total: 1` with `limit: 1`.

Input schema:

```json
{
 "type": "object",
 "properties": {
  "query": {
   "type": "string",
   "minLength": 1,
   "maxLength": 200
  },
  "limit": {
   "type": "integer",
   "minimum": 1,
   "maximum": 50,
   "default": 10
  }
 },
 "additionalProperties": false,
 "required": [
  "query"
 ]
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "query": {
   "type": "string"
  },
  "total": {
   "type": "integer",
   "description": "Matches returned by this call. Never exceeds the requested limit, so it is not a catalogue-wide count."
  },
  "products": {
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer"
     },
     "title": {
      "type": "string"
     },
     "sku": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "price": {
      "type": "string"
     },
     "in_stock": {
      "type": "boolean"
     },
     "type": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "id",
     "title",
     "sku",
     "url",
     "price",
     "in_stock",
     "type"
    ]
   }
  },
  "categories": {
   "type": "array",
   "description": "Matching product categories and tags. Empty unless searchInCategories or searchInTags is enabled, matching what the storefront shows.",
   "items": {
    "type": "object",
    "properties": {
     "id": {
      "type": "integer"
     },
     "name": {
      "type": "string"
     },
     "taxonomy": {
      "type": "string"
     },
     "url": {
      "type": "string"
     },
     "count": {
      "type": "integer"
     }
    },
    "additionalProperties": false,
    "required": [
     "id",
     "name",
     "taxonomy",
     "url",
     "count"
    ]
   }
  }
 },
 "additionalProperties": false,
 "required": [
  "query",
  "total",
  "products",
  "categories"
 ]
}
```

**Example: simple search**

Input:

```json
{
 "query": "dress"
}
```

Response:

```json
{
 "query": "dress",
 "total": 9,
 "products": [
  {
   "id": 111,
   "title": "True passion dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/true-passion-dress/",
   "price": "$360.00 $316.80",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 96,
   "title": "Colorful one piece dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/colorful-one-piece-dress/",
   "price": "$235.00 $206.80",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 102,
   "title": "Black and red dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/black-and-red-dress/",
   "price": "$310.00 $272.80",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 91,
   "title": "Black Western Dress",
   "sku": "ZLY-BWD-091",
   "url": "https://elevated-discount-rules-source.instawp.local/product/black-western-dress/",
   "price": "$120.00 $105.60",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 98,
   "title": "White Floral Dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/white-floral-dress/",
   "price": "$190.00 $167.20",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 6879,
   "title": "Test Dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/test-dress/",
   "price": "$50.00 $44.00",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 110,
   "title": "Winter flower pink dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/winter-flower-pink-dress/",
   "price": "$320.00 $281.60",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 99,
   "title": "Pink dress",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/pink-dress/",
   "price": "$275.00 $242.00",
   "in_stock": true,
   "type": "simple"
  },
  {
   "id": 95,
   "title": "Red top and shorts set",
   "sku": "",
   "url": "https://elevated-discount-rules-source.instawp.local/product/red-top-and-shorts-set/",
   "price": "$260.00 $228.80",
   "in_stock": true,
   "type": "simple"
  }
 ],
 "categories": []
}
```

**Example: the same query with limit 1 (total follows the limit)**

Input:

```json
{
 "query": "dress",
 "limit": 1
}
```

Response:

```json
{
 "status": 200,
 "data": {
  "query": "dress",
  "total": 1,
  "products": [
   {
    "id": 91,
    "title": "Black Western Dress",
    "sku": "ZLY-BWD-091",
    "url": "https://elevated-discount-rules-source.instawp.local/product/black-western-dress/",
    "price": "$120.00 $105.60",
    "in_stock": true,
    "type": "simple"
   }
  ],
  "categories": []
 }
}
```

**Example: query over 200 characters**

Input:

```json
{
 "query": "a...a (201 chars)"
}
```

Response:

```json
{
 "error": {
  "code": "ability_invalid_input",
  "message": "Ability \"elevated-product-search/search-products\" has invalid input. Reason: input[query] must be at most 200 characters long."
 }
}
```

### `elevated-product-search/find-filter-terms`

Finds product categories and tags that can be used as search filters. Annotations: readonly, idempotent. REST method: GET.

Input schema:

```json
{
 "type": "object",
 "properties": {
  "taxonomy": {
   "type": "string",
   "enum": [
    "categories",
    "tags",
    "both"
   ],
   "default": "both"
  },
  "search": {
   "type": "string",
   "maxLength": 100,
   "default": ""
  },
  "page": {
   "type": "integer",
   "minimum": 1,
   "maximum": 1000,
   "default": 1
  },
  "per_page": {
   "type": "integer",
   "minimum": 1,
   "maximum": 50,
   "default": 20
  }
 },
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "categories": {
   "type": "object",
   "properties": {
    "items": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "id": {
        "type": "integer"
       },
       "name": {
        "type": "string"
       },
       "slug": {
        "type": "string"
       },
       "count": {
        "type": "integer"
       },
       "path": {
        "type": "string"
       }
      },
      "additionalProperties": false,
      "required": [
       "id",
       "name",
       "slug",
       "count",
       "path"
      ]
     }
    },
    "page": {
     "type": "integer"
    },
    "per_page": {
     "type": "integer"
    },
    "has_more": {
     "type": "boolean"
    }
   },
   "additionalProperties": false,
   "required": [
    "items",
    "page",
    "per_page",
    "has_more"
   ]
  },
  "tags": {
   "type": "object",
   "properties": {
    "items": {
     "type": "array",
     "items": {
      "type": "object",
      "properties": {
       "id": {
        "type": "integer"
       },
       "name": {
        "type": "string"
       },
       "slug": {
        "type": "string"
       },
       "count": {
        "type": "integer"
       },
       "path": {
        "type": "string"
       }
      },
      "additionalProperties": false,
      "required": [
       "id",
       "name",
       "slug",
       "count",
       "path"
      ]
     }
    },
    "page": {
     "type": "integer"
    },
    "per_page": {
     "type": "integer"
    },
    "has_more": {
     "type": "boolean"
    }
   },
   "additionalProperties": false,
   "required": [
    "items",
    "page",
    "per_page",
    "has_more"
   ]
  }
 },
 "additionalProperties": false,
 "required": [
  "categories",
  "tags"
 ]
}
```

**Example: categories**

Input:

```json
{
 "taxonomy": "categories"
}
```

Response:

```json
{
 "categories": {
  "items": [
   {
    "id": 54,
    "name": "Accessories",
    "slug": "accessories",
    "count": 5,
    "path": "Accessories"
   },
   {
    "id": 50,
    "name": "BXG% Test",
    "slug": "bxg-test",
    "count": 1,
    "path": "BXG% Test"
   },
   {
    "id": 52,
    "name": "Computers",
    "slug": "computers",
    "count": 3,
    "path": "Computers"
   },
   {
    "id": 19,
    "name": "Dress",
    "slug": "dress",
    "count": 4,
    "path": "Dress"
   },
   {
    "id": 264,
    "name": "Dresses",
    "slug": "dresses",
    "count": 2,
    "path": "Dresses"
   },
   {
    "id": 278,
    "name": "EDR E2E Apparel",
    "slug": "edr-e2e-apparel",
    "count": 4,
    "path": "EDR E2E Apparel"
   },
   {
    "id": 263,
    "name": "Electronics",
    "slug": "electronics",
    "count": 0,
    "path": "Electronics"
   },
   {
    "id": 109,
    "name": "Eligible Category",
    "slug": "eligible-category",
    "count": 0,
    "path": "Eligible Category"
   },
   {
    "id": 20,
    "name": "Jacket",
    "slug": "jacket",
    "count": 2,
    "path": "Jacket"
   },
   {
    "id": 53,
    "name": "Laptops",
    "slug": "laptops",
    "count": 2,
    "path": "Computers > Laptops"
   },
   {
    "id": 265,
    "name": "LimitTest 1",
    "slug": "limittest-1",
    "count": 0,
    "path": "LimitTest 1"
   },
   {
    "id": 266,
    "name": "LimitTest 2",
    "slug": "limittest-2",
    "count": 0,
    "path": "LimitTest 2"
   },
   {
    "id": 267,
    "name": "LimitTest 3",
    "slug": "limittest-3",
    "count": 0,
    "path": "LimitTest 3"
   },
   {
    "id": 91,
    "name": "Pipeline Test Cat",
    "slug": "pipeline-test-cat",
    "count": 0,
    "path": "Pipeline Test Cat"
   },
   {
    "id": 275,
    "name": "PreserveTest",
    "slug": "preservetest",
    "count": 0,
    "path": "PreserveTest"
   },
   {
    "id": 24,
    "name": "Skirt",
    "slug": "skirt",
    "count": 0,
    "path": "Skirt"
   },
   {
    "id": 110,
    "name": "Special",
    "slug": "special",
    "count": 0,
    "path": "Special"
   },
   {
    "id": 18,
    "name": "Sweather",
    "slug": "sweather",
    "count": 1,
    "path": "Sweather"
   },
   {
    "id": 15,
    "name": "Uncategorized",
    "slug": "uncategorized",
    "count": 2,
    "path": "Uncategorized"
   }
  ],
  "page": 1,
  "per_page": 20,
  "has_more": false
 },
 "tags": {
  "items": [],
  "page": 1,
  "per_page": 20,
  "has_more": false
 }
}
```

**Example: invalid taxonomy value (the error names the valid ones)**

Input:

```json
{
 "taxonomy": "category"
}
```

Response:

```json
{
 "error": {
  "code": "ability_invalid_input",
  "message": "Ability \"elevated-product-search/find-filter-terms\" has invalid input. Reason: input[taxonomy] is not one of categories, tags, and both."
 }
}
```

### `elevated-product-search/list-searchable-custom-fields`

Lists product custom field keys that can be added to the search scope. Annotations: readonly, idempotent. REST method: GET.

Input schema:

```json
{
 "type": "object",
 "properties": {
  "search": {
   "type": "string",
   "maxLength": 100,
   "default": ""
  },
  "per_page": {
   "type": "integer",
   "minimum": 1,
   "maximum": 50,
   "default": 50
  }
 },
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "items": {
   "type": "array",
   "items": {
    "type": "string"
   }
  },
  "per_page": {
   "type": "integer"
  },
  "has_more": {
   "type": "boolean"
  }
 },
 "additionalProperties": false,
 "required": [
  "items",
  "per_page",
  "has_more"
 ]
}
```

**Example:**

Input:

```json
{}
```

Response:

```json
{
 "items": [
  "abc",
  "checkboxtest",
  "checkboxtest_copy",
  "selecttest"
 ],
 "per_page": 50,
 "has_more": false
}
```

### `elevated-product-search/get-index-status`

Reports whether the search index exists, how many documents it holds and whether a rebuild is running. Annotations: readonly, idempotent. REST method: GET.

Input schema:

```json
{
 "type": "object",
 "properties": [],
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "index_exists": {
   "type": "boolean"
  },
  "indexed_documents": {
   "type": "integer"
  },
  "published_products": {
   "type": "integer"
  },
  "excluded_products": {
   "type": "object",
   "properties": {
    "out_of_stock": {
     "type": "integer"
    },
    "total": {
     "type": "integer"
    }
   },
   "additionalProperties": false,
   "required": [
    "out_of_stock",
    "total"
   ]
  },
  "last_rebuild": {
   "type": [
    "string",
    "null"
   ]
  },
  "is_rebuilding": {
   "type": "boolean"
  },
  "rebuild_id": {
   "type": [
    "string",
    "null"
   ]
  },
  "storage_writable": {
   "type": "boolean"
  }
 },
 "additionalProperties": false,
 "required": [
  "index_exists",
  "indexed_documents",
  "published_products",
  "excluded_products",
  "last_rebuild",
  "is_rebuilding",
  "rebuild_id",
  "storage_writable"
 ]
}
```

**Example:**

Input:

```json
{}
```

Response:

```json
{
 "index_exists": true,
 "indexed_documents": 43,
 "published_products": 43,
 "excluded_products": {
  "out_of_stock": 0,
  "total": 0
 },
 "last_rebuild": "2026-08-26 00:17:15",
 "is_rebuilding": false,
 "rebuild_id": null,
 "storage_writable": true
}
```

### `elevated-product-search/rebuild-index`

Drops the search index and builds it again from every published product. Requires confirmation. Annotations: write, destructive, not idempotent. REST method: POST.

Drops the index and rebuilds it from every published product. `force: true` clears a rebuild lock left behind by an interrupted run; without it a stuck lock can only be waited out. A rebuild that cannot start reports `state: "failed"` and `get-rebuild-progress` carries the cause in `message`.

Input schema:

```json
{
 "type": "object",
 "properties": {
  "confirm": {
   "type": "boolean"
  },
  "force": {
   "type": "boolean",
   "default": false
  }
 },
 "additionalProperties": false,
 "required": [
  "confirm"
 ]
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "state": {
   "type": "string",
   "enum": [
    "complete",
    "in_progress",
    "failed"
   ]
  },
  "forced": {
   "type": "boolean"
  },
  "indexed_documents": {
   "type": "integer"
  },
  "message": {
   "type": "string"
  }
 },
 "additionalProperties": false,
 "required": [
  "state",
  "forced",
  "indexed_documents",
  "message"
 ]
}
```

**Example: without confirm (fails before any side effect)**

Input:

```json
{}
```

Response:

```json
{
 "error": {
  "code": "ability_invalid_input",
  "message": "Ability \"elevated-product-search/rebuild-index\" has invalid input. Reason: confirm is a required property of input."
 }
}
```

**Example: confirmed rebuild**

Input:

```json
{
 "confirm": true
}
```

Response:

```json
{
 "state": "complete",
 "forced": false,
 "indexed_documents": 43,
 "message": "The search index was rebuilt."
}
```

**Example: a rebuild that could not start**

Input:

```json
{
 "confirm": true
}
```

Response:

```json
{
 "state": "failed",
 "forced": false,
 "indexed_documents": 43,
 "message": "The search index could not be rebuilt. Enable debug mode and check the logs for the cause."
}
```

### `elevated-product-search/get-rebuild-progress`

Retrieves progress for the running or most recent index rebuild. Annotations: readonly, idempotent. REST method: GET.

`status` is `idle` when nothing has run, then `complete`, `failed`, or `cancelled`. After a failed start, `message` carries the cause.

Input schema:

```json
{
 "type": "object",
 "properties": [],
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "status": {
   "type": "string",
   "enum": [
    "idle",
    "processing",
    "complete",
    "error"
   ]
  },
  "is_rebuilding": {
   "type": "boolean"
  },
  "products_done": {
   "type": "integer"
  },
  "total_products": {
   "type": "integer"
  },
  "message": {
   "type": "string"
  },
  "rebuild_id": {
   "type": [
    "string",
    "null"
   ]
  }
 },
 "additionalProperties": false,
 "required": [
  "status",
  "is_rebuilding",
  "products_done",
  "total_products",
  "message",
  "rebuild_id"
 ]
}
```

**Example: after a completed rebuild**

Input:

```json
{}
```

Response:

```json
{
 "status": "complete",
 "is_rebuilding": false,
 "products_done": 43,
 "total_products": 43,
 "message": "Successfully indexed 43 products",
 "rebuild_id": "rebuild-1788134738"
}
```

**Example: idle, before anything has run**

Input:

```json
{}
```

Response:

```json
{
 "status": "idle",
 "is_rebuilding": false,
 "products_done": 0,
 "total_products": 0,
 "message": "",
 "rebuild_id": null
}
```

**Example: after a failed start (message carries the cause)**

Input:

```json
{}
```

Response:

```json
{
 "status": "error",
 "is_rebuilding": false,
 "products_done": 0,
 "total_products": 0,
 "message": "The search engine could not be started: SQLSTATE[HY000] [2002] No such file or directory",
 "rebuild_id": null
}
```

### `elevated-product-search/get-index-schedule`

Retrieves the scheduled index rebuild settings and the next run time. Annotations: readonly, idempotent. REST method: GET.

Input schema:

```json
{
 "type": "object",
 "properties": [],
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "enabled": {
   "type": "boolean"
  },
  "interval": {
   "type": "string",
   "enum": [
    "daily",
    "weekly",
    "monthly"
   ]
  },
  "time": {
   "type": "string"
  },
  "scheduled": {
   "type": "boolean"
  },
  "next_run": {
   "type": [
    "string",
    "null"
   ]
  },
  "next_run_gmt": {
   "type": [
    "string",
    "null"
   ]
  },
  "wp_cron_disabled": {
   "type": "boolean"
  }
 },
 "additionalProperties": false,
 "required": [
  "enabled",
  "interval",
  "time",
  "scheduled",
  "next_run",
  "next_run_gmt",
  "wp_cron_disabled"
 ]
}
```

**Example:**

Input:

```json
{}
```

Response:

```json
{
 "enabled": false,
 "interval": "weekly",
 "time": "00:00",
 "scheduled": false,
 "next_run": null,
 "next_run_gmt": null,
 "wp_cron_disabled": false
}
```

### `elevated-product-search/get-environment-status`

Reports the versions, PHP extensions and WordPress settings Elevated Product Search depends on. Annotations: readonly, idempotent. REST method: GET.

Input schema:

```json
{
 "type": "object",
 "properties": [],
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "plugin_version": {
   "type": "string"
  },
  "wordpress_version": {
   "type": "string"
  },
  "php_version": {
   "type": "string"
  },
  "multisite": {
   "type": "boolean"
  },
  "woocommerce_active": {
   "type": "boolean"
  },
  "woocommerce_version": {
   "type": [
    "string",
    "null"
   ]
  },
  "pdo_available": {
   "type": "boolean"
  },
  "pdo_sqlite_available": {
   "type": "boolean"
  },
  "pdo_mysql_available": {
   "type": "boolean"
  },
  "index_storage_writable": {
   "type": "boolean"
  },
  "wp_cron_disabled": {
   "type": "boolean"
  },
  "debug_log_enabled": {
   "type": "boolean"
  },
  "plugin_logging_enabled": {
   "type": "boolean"
  },
  "published_products": {
   "type": "integer"
  }
 },
 "additionalProperties": false,
 "required": [
  "plugin_version",
  "wordpress_version",
  "php_version",
  "multisite",
  "woocommerce_active",
  "woocommerce_version",
  "pdo_available",
  "pdo_sqlite_available",
  "pdo_mysql_available",
  "index_storage_writable",
  "wp_cron_disabled",
  "debug_log_enabled",
  "plugin_logging_enabled",
  "published_products"
 ]
}
```

**Example:**

Input:

```json
{}
```

Response:

```json
{
 "plugin_version": "1.1.0",
 "wordpress_version": "7.1",
 "php_version": "8.2.29",
 "multisite": false,
 "woocommerce_active": true,
 "woocommerce_version": "10.7.0",
 "pdo_available": true,
 "pdo_sqlite_available": true,
 "pdo_mysql_available": true,
 "index_storage_writable": true,
 "wp_cron_disabled": false,
 "debug_log_enabled": true,
 "plugin_logging_enabled": false,
 "published_products": 43
}
```

### `elevated-product-search/get-debug-logs`

Retrieves recent Elevated Product Search debug log entries with server paths removed. Annotations: readonly, idempotent. REST method: GET.

Server paths are redacted from log messages before they are returned.

Input schema:

```json
{
 "type": "object",
 "properties": {
  "page": {
   "type": "integer",
   "minimum": 1,
   "maximum": 1000,
   "default": 1
  },
  "per_page": {
   "type": "integer",
   "minimum": 1,
   "maximum": 200,
   "default": 50
  },
  "search": {
   "type": "string",
   "maxLength": 200,
   "default": ""
  }
 },
 "additionalProperties": false,
 "default": {}
}
```

Output schema:

```json
{
 "type": "object",
 "properties": {
  "available": {
   "type": "boolean"
  },
  "entries": {
   "type": "array",
   "items": {
    "type": "object",
    "properties": {
     "timestamp": {
      "type": [
       "string",
       "null"
      ]
     },
     "level": {
      "type": "string"
     },
     "message": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "timestamp",
     "level",
     "message"
    ]
   }
  },
  "total": {
   "type": "integer"
  },
  "page": {
   "type": "integer"
  },
  "per_page": {
   "type": "integer"
  },
  "has_more": {
   "type": "boolean"
  },
  "message": {
   "type": "string"
  }
 },
 "additionalProperties": false,
 "required": [
  "available",
  "entries",
  "total",
  "page",
  "per_page",
  "has_more",
  "message"
 ]
}
```

**Example: two most recent entries**

Input:

```json
{
 "per_page": 2
}
```

Response:

```json
{
 "available": true,
 "entries": [
  {
   "timestamp": "2026-08-08 08:39:25",
   "level": "info",
   "message": "Index rebuild complete: 40 products indexed"
  },
  {
   "timestamp": "2026-08-08 08:37:50",
   "level": "info",
   "message": "Index rebuild complete: 40 products indexed"
  }
 ],
 "total": 16,
 "page": 1,
 "per_page": 2,
 "has_more": true,
 "message": ""
}
```

## Error catalog

Every schema failure is a `WP_Error` with code `ability_invalid_input`; handler-level failures carry their own codes; the REST surface adds HTTP-level rejections. The messages:

- `Ability "elevated-product-search/search-products" has invalid input. Reason: input[query] must be at most 200 characters long.`
- `Ability "elevated-product-search/find-filter-terms" has invalid input. Reason: input[taxonomy] is not one of categories, tags, and both.`
- `Ability "elevated-product-search/update-settings" has invalid input. Reason: input[settings][fuzzyMatching] is not one of off, soft, normal, and hard.`
- `Ability "elevated-product-search/update-settings" has invalid input. Reason: nope is not a valid property of Object.`
- `Ability "elevated-product-search/update-settings" has invalid input. Reason: settings is a required property of input.`
- `empty_settings_patch`: `The settings patch does not contain any settings to update.`
- `Ability "elevated-product-search/reset-settings" has invalid input. Reason: confirm is a required property of input.`
- `Ability "elevated-product-search/rebuild-index" has invalid input. Reason: confirm is a required property of input.`
- `405` `Read-only abilities require GET method.`, `Abilities that perform updates require POST method.`, `Abilities that perform destructive actions require DELETE method.` (REST method mapping)
- `401` `Sorry, you are not allowed to execute this ability.` (unauthenticated)
- `404` `Ability not found.` (agent access switched off by the site owner)
