ReaktlyDocs
Integrations

WordPress Integration

Push WordPress posts and pages into a Reaktly knowledge base.

Overview

Two ways to get WordPress content into Reaktly:

  1. Push from WordPress — your site forwards each post to Reaktly when it is saved (recommended: updates arrive immediately)
  2. Pull with a script — a scheduled job reads the WordPress REST API and pushes

Both end in the same place: items in your knowledge base, classified as ARTICLE (Source types).

A packaged WordPress plugin is on the roadmap. Until it ships, the two approaches below are the supported paths — both are small and self-contained.

Option 1: Push from WordPress

Reaktly exposes a WordPress endpoint that accepts a post object (or an array of them):

POST https://api.reaktly.com/integrations/wordpress/sync
x-api-key: YOUR_API_KEY

Add a small mu-plugin to your theme's functions.php (or better, wp-content/mu-plugins/):

<?php
add_action('save_post', function ($post_id) {
    if (wp_is_post_revision($post_id) || get_post_status($post_id) !== 'publish') {
        return;
    }

    $post = get_post($post_id);

    wp_remote_post('https://api.reaktly.com/integrations/wordpress/sync', [
        'headers' => [
            'Content-Type' => 'application/json',
            'x-api-key'    => 'YOUR_API_KEY',
        ],
        'body' => wp_json_encode([
            'id'      => (string) $post->ID,
            'title'   => ['rendered' => get_the_title($post)],
            'content' => ['rendered' => apply_filters('the_content', $post->post_content)],
            'link'    => get_permalink($post),
        ]),
        'timeout' => 15,
    ]);
});

Every published save re-syncs that post. Send an array to sync several posts in one call.

Option 2: Pull with a script

Use the WordPress REST API when you prefer a scheduled job (for example an initial import):

import hashlib
import requests

WP_URL = "https://your-site.com/wp-json/wp/v2"
REAKTLY_API = "https://api.reaktly.com"
API_KEY = "your-api-key"

def sync_posts():
    posts = requests.get(f"{WP_URL}/posts?per_page=100").json()

    items = [{
        "integrationId": "wp-integration-id",
        "sourceType": "ARTICLE",
        "externalId": f"wp-post-{post['id']}",
        "data": {
            "title": post["title"]["rendered"],
            "content": post["content"]["rendered"],
            "url": post["link"],
            "hash": hashlib.sha256(post["modified"].encode()).hexdigest(),
        },
    } for post in posts]

    response = requests.post(
        f"{REAKTLY_API}/ingest/bulk",
        json={"items": items},
        headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
        timeout=30,
    )
    response.raise_for_status()
    print(response.json()["jobCount"], "items queued")

The hash field makes the job cheap: unchanged posts are skipped (Change detection).

content.rendered arrives as HTML. Reaktly normalises it during processing, but you get cleaner answers when you strip navigation, footers, and shortcodes before sending — send post_content rather than a rendered page.

Pages and custom post types

The push endpoint accepts any post-shaped object with an id. For pages, use /wp-json/wp/v2/pages in the script variant, or the same save_post hook filtered to your post types. Give each type a distinct sourceOrigin (e.g. wordpress-posts, wordpress-pages) so cleanup after a full sync stays scoped.

On this page