This guide explains how to add your own custom entries to the Jetpack Activity Log from your plugin or site code.
Jetpack Activity Log entries created with this API appear alongside other events like posts published or plugins updated. This is useful if you want to surface meaningful events to site administrators without building your own activity or audit log UI. This is a developer-level guide that involves writing custom code.
Requirements
- Jetpack plugin version 15.9 or higher, or
- Jetpack Sync package version 4.38 or higher (if your plugin requires Sync directly).
- The
jp_act_log_eventcustom post type is registered automatically when Sync loads. You do not need to register it yourself. - The caller must have the
manage_optionscapability (typically a site administrator).
How to add an Activity Log entry
You can create custom Activity Log entries in three main ways:
- From PHP using the helper class (recommended).
- From a REST client.
- Directly using
wp_insert_post().
Add an entry from PHP (recommended)
Use the Activity_Log_Event helper class to validate and create entries.
use Automattic\Jetpack\Sync\Activity_Log_Event;
$post_id = Activity_Log_Event::create( array(
'title' => 'Membership sync failed',
'content' => 'Remote API returned 401. Retry queued.',
'source' => 'my-plugin',
'severity' => 'error',
) );
if ( false === $post_id ) {
// Validation failed (missing/invalid title or content, bad severity).
}
On success, create() returns the jp_act_log_event post ID.
If validation fails, it returns false.
Using the helper is the recommended approach, because it handles validation and ensures a consistent data format for Activity Log entries.
Add an entry from a REST client
You can also create entries using the WordPress REST API.
Endpoint
textPOST /wp-json/wp/v2/activity-log-events
Content-Type: application/json
Authorization: OAuth token with admin scope
Request body
json {
"title": "Membership sync failed",
"content": "Remote API returned 401. Retry queued.",
"source": "my-plugin",
"severity": "error"
}
The authenticated user must have manage_options capability. The resulting Activity Log entry will be attributed to that user as the actor.
Add an entry using wp_insert_post()
You can also create events directly as jp_act_log_event posts. The post_content field should contain a JSON‑encoded payload with the same properties used elsewhere.
phpwp_insert_post(
array(
'post_type' => 'jp_act_log_event',
'post_status' => 'publish',
'post_title' => 'Cache flushed',
'post_content'=> wp_json_encode(
array(
'title' => 'Cache flushed',
'content' => 'Manual cache flush during incident response.',
'source' => 'my-snippet',
'severity' => 'info',
)
),
)
);
You are responsible for validating these values yourself when using wp_insert_post(). To avoid invalid entries, prefer the Activity_Log_Event helper whenever possible.
Field definitions
Each Activity Log event supports the following properties:
- title
- Type: string
- Max length: 200 characters
- Plain text only
- Required
- content
- Type: string
- Max length: 5,000 characters
- Plain text only
- Required
- source
- Type: string
- Max length: 100 characters
- Identifier for the originating tool (for example,
my-plugin). - Default:
Custom entry - Optional
- severity
- Type: enum
- Allowed values:
info,success,warning,error - Default:
info - Optional
What site owners see
Custom entries appear in the site’s Activity Log as normal events, labeled as custom events. In the Activity Log:
- The title is used as the headline of the event.
- The actor is the WordPress user who made the API call (for example, via PHP or REST).
Limitations and behavior
Custom Activity Log entries created with this API have the following behavior:
- Not editable
Entries are write‑once. Thejp_act_log_eventcustom post type denies alledit_*anddelete_*capabilities. - Not auto‑publicized
Entries will not be shared via Jetpack Social, even if a third‑party plugin adds publicize support for the custom post type. - Not included in sitemaps
Thejp_act_log_eventpost type is explicitly excluded from Jetpack sitemaps. - Front‑end private
The post type uses:public => falsepublicly_queryable => falseexclude_from_search => true