> This page is for Tools.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.moveworks.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.moveworks.com/_mcp/server.

# WordPress

# Overview

WordPress is a content management system used to publish pages and blog posts. The Classic Ingestion connector indexes publicly available pages and posts and makes them searchable in the Moveworks AI Assistant.

## Access Requirements

See [WordPress Access Requirements](/service-management/access-requirements/knowledge-base-systems/wordpress-access-requirements) for instructions on how to connect Moveworks to your WordPress instance.

## Permissions

The Classic Ingestion connector for WordPress does not mirror source permissions. All indexed content is visible to all employees in the AI Assistant search experience.

# Content Types Supported within WordPress

* Pages
* Blog Posts

# How Moveworks Integrates with WordPress

Moveworks has Indexed Search support for publicly available blog posts and pages within WordPress. The following diagram illustrates the high-level architecture of how Moveworks integrates with the WordPress Sites:

![](https://files.readme.io/a23d33b-Untitled_-_2024-06-24T143917.639.png)

This is a live integration which means we poll for knowledge articles every four hours. This is done so that the enterprise cache is updated with relevant snippets for answers.

Our enterprise cache stores the knowledge documents and generates relevant knowledge snippets by understanding the content. This is also where we store redirect URLs in order to direct users to where the knowledge article is located and can be read.

## How do we fetch knowledge articles from WordPress

We use the following APIs to fetch the knowledge articles that you want Moveworks to ingest.

### Fetch all Pages

```bash
curl --location --globoff 'https://{{wordpress_url}}/wp-json/wp/v2/pages?per_page=100&page=1&status=publish' \
--header 'Accept: application/json' \
--header 'Authorization: Basic Basic <base64({{wordpress_username}}:{{wordpress_password}})>'
```

### Fetch all Posts

```bash
curl --location --globoff 'https://{{wordpress_url}}/wp-json/wp/v2/posts?per_page=100&page=1&status=publish' \
--header 'Accept: application/json' \
--header 'Authorization: Basic Basic <base64({{wordpress_username}}:{{wordpress_password}})>'
```

## Integration Scope

### Content

Our knowledge ingestion engine works on ingesting the `content.rendered` section from the API response which is an HTML block and we ingest and snippetize the content based on this HTML.

# Configuring WordPress Ingestion with Custom Mappers

WordPress requires custom mappers to map the API response to a format that Moveworks can ingest. Because the WordPress REST API returns pages and posts in a consistent JSON structure, the mapper configuration is fairly standard.

## Prerequisites

* A WordPress connector has been created with the necessary permissions. See the [WordPress Access Requirements](/service-management/access-requirements/knowledge-base-systems/wordpress-access-requirements) for details.
* The WordPress REST API is accessible at `https://<your-site>/wp-json/wp/v2/`.

## Setup Knowledge Ingestion in Advanced Mode

Start by creating a new ingestion under **Search > Configure Search > Classic Ingestion > Internal Knowledge**.

1. Select the **Connector** created for WordPress and provide a name for the ingestion under *Ingestion Name*.
2. Choose a **Domain** — the functional area of employee service most related to the knowledge being ingested.
3. Toggle on **Advanced Mode** (top-right corner of the Setup Knowledge Bases step).
4. Select **Generic Config** as the ingestion system. Generic Config allows you to ingest content from any API response by mapping the response fields to Moveworks internal attributes.

### Start URLs

Enter the WordPress API endpoint for the content type you want to ingest. You will need to create a separate ingestion configuration for pages and posts.

**For Pages:**

```
https://<your-wordpress-site>/wp-json/wp/v2/pages?per_page=100&page=1&status=publish
```

**For Posts:**

```
https://<your-wordpress-site>/wp-json/wp/v2/posts?per_page=100&page=1&status=publish
```

Set the **Type of content** to **Article List**, since the WordPress API returns a flat list of articles (no folder hierarchy).

## Response Mapper

The Response Mapper tells Moveworks how to traverse the API response and handle pagination. Select **KNOWLEDGE_URL_TYPE_ARTICLE_LIST** as the Type in **Response Mapper** and use the following configuration:

```json
{
  "knowledge_urls": {
    "CONDITIONAL()": {
      "condition": "NOT (NOT (response))",
      "on_pass": {
        "FLATTEN()": [
          {
            "CONDITIONAL()": {
              "condition": "$INTEGER(source_url.parsed_url.query_params.page) < $INTEGER(headers['x-wp-totalpages'])",
              "on_pass": {
                "parsed_url": {
                  "base_url": "source_url.parsed_url.base_url",
                  "query_params": {
                    "page": {
                      "EVAL()": {
                        "expression": "page + 1",
                        "args": "source_url.parsed_url.query_params"
                      }
                    },
                    "status": "source_url.parsed_url.query_params.status",
                    "per_page": "source_url.parsed_url.query_params.per_page"
                  }
                },
                "type": "\"ARTICLE_LIST\"",
                "method": "\"GET\"",
                "headers": {
                  "Accept": "\"application/json\""
                }
              }
            }
          }
        ]
      },
      "on_fail": "[]"
    }
  },
  "knowledge_articles": {
    "CONDITIONAL()": {
      "condition": "NOT(NOT(response))",
      "on_pass": "response",
      "on_fail": "[]"
    }
  }
}
```

**How this works:**

* `knowledge_urls` handles pagination by comparing the current `page` query parameter against the `x-wp-totalpages` response header that WordPress provides. If there are more pages remaining, it constructs the next page URL by incrementing `page` by 1. Once all pages have been fetched, pagination stops.
* `knowledge_articles` passes the current page of results through to the Article Mapper.

## Article Mapper

The Article Mapper maps individual WordPress post/page fields to Moveworks internal article attributes. Use the following configuration:

**For Pages:**

```json
{
  "created_at": "$TIMECONV(date_gmt)",
  "updated_at": "$TIMECONV(modified_gmt)",
  "article_id": "$TEXT($INTEGER(id))",
  "title": "title.rendered",
  "body": "content.rendered",
  "article_url": "link",
  "article_state": "\"PUBLISHED\"",
  "article_visibility": "\"VISIBLE\"",
  "article_class": "\"CONTENT_ITEM\"",
  "article_hierarchies": [
    {
      "tier_values": "[\"\"]",
      "tier_label": "\"KNOWLEDGE_BASE\""
    }
  ]
}
```

**For Posts:**

```json
{
  "created_at": "$TIMECONV(date_gmt)",
  "updated_at": "$TIMECONV(modified_gmt)",
  "article_id": "$TEXT($INTEGER(id))",
  "title": "title.rendered",
  "body": "content.rendered",
  "article_url": "link",
  "article_state": "\"PUBLISHED\"",
  "article_visibility": "\"VISIBLE\"",
  "article_class": "\"CONTENT_ITEM\"",
  "article_hierarchies": [
    {
      "tier_values": "[\"\"]",
      "tier_label": "\"KNOWLEDGE_BASE\""
    }
  ]
}
```

> **Info**
>
> The Article Mapper is the same for both pages and posts since the WordPress REST API uses a consistent response structure for both content types. The key difference is the Start URL — use `/wp/v2/pages` for pages and `/wp/v2/posts` for posts.

**Field mapping reference:**

| Moveworks Attribute  | WordPress API Field | Description                                                     |
| -------------------- | ------------------- | --------------------------------------------------------------- |
| `created_at`         | `date_gmt`          | Article creation timestamp (GMT)                                |
| `updated_at`         | `modified_gmt`      | Last modified timestamp (GMT)                                   |
| `article_id`         | `id`                | Unique WordPress post/page ID                                   |
| `title`              | `title.rendered`    | Rendered HTML title                                             |
| `body`               | `content.rendered`  | Rendered HTML content body                                      |
| `article_url`        | `link`              | Public permalink URL                                            |
| `article_state`      | —                   | Set to `PUBLISHED` (the Start URL filters for `status=publish`) |
| `article_visibility` | —                   | Set to `VISIBLE` for all employees                              |

## Validation

Once you have saved the ingestion configuration, the ingestion pipeline will run in the background. You can track the status on the [Indexed Content View](/tool-studio/enterprise-search/monitor-indexed-content).

Search for your WordPress articles by title — if they appear in the console, they have been ingested successfully.