Using the Simple History REST API efficiently with LLMs and AI agents

If you’re building AI-powered tools that read your WordPress activity log — whether it’s a Claude Code skill, a custom GPT, or any LLM-based agent — you’ll want to keep API responses as small as possible. Every extra byte costs tokens, and tokens cost money and context window space.

Here are a few tips we have found useful to keep request size low to lower token usage (meaning cheaper requests!) when using the history REST API.

Oh, and a tip: give your AI the URL to this page and they will understand how to use the API the best way, using the tricks outlined below! 🙂

Using fields parameter

The Simple History REST API supports the same _fields parameter as WordPress core, including dot notation for nested objects. This makes a massive difference.

A default request may look like this:

curl -u 'user:app_password' \
  'https://example.com/wp-json/simple-history/v1/events?per_page=10'

This will return the full event object for each entry: message, HTML-formatted message, details HTML, context with all debug data, initiator data with avatar markup, action links, and more. For 10 events, this can easily be 50–500 KB of JSON — most of which an LLM will never use.

The solution: _fields with dot notation

Request only what you need:

curl -u 'user:app_password' \
  'https://example.com/wp-json/simple-history/v1/events?per_page=10&_fields=date_gmt,message,loglevel,logger,initiator,initiator_data.user_display_name,initiator_data.user_login,subsequent_occasions_count'

This returns a clean, minimal response:

[
  {
    "date_gmt": "2026-03-26 21:45:01",
    "message": "Found an update to plugin \"Advanced Custom Fields\"",
    "loglevel": "notice",
    "logger": "AvailableUpdatesLogger",
    "initiator": "wp",
    "initiator_data": {
      "user_display_name": null,
      "user_login": null
    },
    "subsequent_occasions_count": 1
  },
  {
    "date_gmt": "2026-03-26 14:17:58",
    "message": "Added application password \"EP WP Site Dashboard\" for user \"par\"",
    "loglevel": "info",
    "logger": "SimpleUserLogger",
    "initiator": "wp_user",
    "initiator_data": {
      "user_display_name": "Pär Thernström",
      "user_login": "par"
    },
    "subsequent_occasions_count": 1
  }
]

The initiator field tells you what triggered the event — wp for WordPress core actions (cron, updates), wp_user for logged-in users, wp_cli for WP-CLI commands, and web_user for anonymous visitors (e.g. failed logins). This is useful for filtering or labeling events without having to infer from null user_display_name.

~15 KB instead of ~500 KB for the same 10 events.

Why dot notation matters

The initiator_data object contains seven fields, including a user_image field with a full <img> HTML tag (srcset and all). For a browser UI, that’s handy. For an LLM reading JSON, it’s pure waste.

With dot notation you pick exactly the sub-fields you need:

_fields=initiator_data.user_display_name,initiator_data.user_login

Instead of the full object:

{
  "user_id": "1",
  "user_login": "par",
  "user_email": "par@example.com",
  "user_image": "<img alt='Avatar photo' src='...' srcset='... 2x' class='avatar avatar-32 photo' height='32' width='32' loading='lazy' decoding='async'/>",
  "user_avatar_url": "https://example.com/.../avatar-96x96.jpg",
  "user_profile_url": "https://example.com/wp-admin/profile.php",
  "user_display_name": "Pär Thernström"
}

You get just:

{
  "user_display_name": "Pär Thernström",
  "user_login": "par"
}

Available fields to pick from

FieldWhat it contains
date_gmtEvent timestamp in GMT
date_localEvent timestamp in site’s timezone
messageHuman-readable event description (pre-interpolated)
message_htmlSame but with HTML formatting
message_uninterpolatedTemplate with {placeholders}
logleveldebug, info, notice, warning, error, critical
loggerLogger class name (e.g. SimplePluginLogger)
initiatorWho triggered it: wp_user, wp, web_user
initiator_data.*User details (supports dot notation)
ip_addressesIP address(es) of the request
subsequent_occasions_countNumber of similar grouped events
contextFull context data (large — include only when needed)
details_dataStructured change details
details_htmlHTML-formatted change details

Tips for AI agent builders

  1. Start minimal. Use message + initiator + initiator_data.user_display_name + date_gmt as your baseline. Add fields only when needed. The initiator field lets you distinguish WordPress system events, user actions, WP-CLI commands, and anonymous visitors at a glance.
  2. Skip HTML fields. message_html, details_html, and initiator_data.user_image are for browser rendering, not LLM consumption.
  3. Use subsequent_occasions_count to show event grouping (e.g. “Failed login +10 attempts”) without fetching each individual event.
  4. Filter server-side with search, date_from, date_to, and per_page query parameters — don’t fetch 100 events and filter in your prompt.
  5. This works because Simple History’s REST API goes through WordPress core’s rest_filter_response_fields(), which has supported dot notation since WordPress 4.7. No plugin changes needed — it just works.