Contents
On this page
Create Alert Rule - Plugixa Activity Log
POST /plugixa-activity-log/v1/rules
Create an alert rule: the events it matches and where the alert goes.
Needs settings access (see who can call what). Needs Plugixa Activity Log Pro, with the Alert rules module on under Plugixa Activity Log -> Monitors.
Note. Channels are cleaned rather than refused. Only the first 10 are kept, and a channel with an unknown
typeor an emptytargetis dropped without an error. Codes of 9000 and above, and addresses that are not a valid IP or CIDR range, are dropped from the conditions the same way. Read the response to see what was stored.
Request
POST https://your-site.example/wp-json/plugixa-activity-log/v1/rules
Request body
Content type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Must not be blank. Cut to 191 characters. |
enabled |
boolean |
No | Defaults to true. Only true, 1, "1" and "true" count as on. |
conditions |
object |
No | What an event must match. See the table below. Left out, the rule matches every event. |
channels |
array |
Yes | At least one usable channel. See the table below. |
throttle_minutes |
integer |
No | 0 (the default) sends every match. Otherwise the rule fires at most once in this many minutes. 0 to 1440; values outside are brought into range. |
Conditions
Every condition that is filled in must hold, and an empty one does not narrow.
| Field | Type | Description |
|---|---|---|
codes |
integer[] |
Event codes. Codes of 9000 and above (the log’s own trail) are dropped. |
groups |
string[] |
Event group keys, as the group filter of List Events uses them, such as authentication. |
min_severity |
string |
informational, low, medium, high or critical. Anything else is stored as empty. |
severities |
string[] |
An exact list of the same severity names. No field in the rule editor sets it. |
user_roles |
string[] |
Role slugs the person had at the time. |
user_ids |
integer[] |
WordPress user ids. No field in the rule editor sets it. |
ips |
string[] |
Single addresses or CIDR ranges, such as 203.0.113.0/24. |
object_types |
string[] |
Object types, such as user or post. |
search |
string |
Text that must appear in the message, the object or the login, ignoring case. At most 100 characters. |
Channels
| Field | Type | Required | Description |
|---|---|---|---|
type |
string |
Yes | email, slack, discord, teams or webhook. |
target |
string |
Yes | For email, an email address. For the others, an https:// address that is not this machine or a private network address. |
secret |
string |
No | webhook only: the key used to sign each delivery. Ignored for other types. At most 200 characters. |
A webhook channel receives a signed JSON POST: see Webhook events. Saving a rule is recorded in the log as event 9120.
{
"name": "Administrator sign-ins from outside the office",
"enabled": true,
"conditions": {
"groups": ["authentication"],
"min_severity": "medium",
"user_roles": ["administrator"],
"ips": ["203.0.113.0/24"]
},
"channels": [
{ "type": "email", "target": "security@example.com" },
{ "type": "webhook", "target": "https://hooks.example.com/activity", "secret": "a-signing-secret" }
],
"throttle_minutes": 15
}
Responses
201 Created. data is the new rule.
{
"success": true,
"data": {
"id": 4,
"name": "Administrator sign-ins from outside the office",
"enabled": true,
"conditions": {
"codes": [],
"groups": ["authentication"],
"min_severity": "medium",
"severities": [],
"user_roles": ["administrator"],
"user_ids": [],
"ips": ["203.0.113.0/24"],
"object_types": [],
"search": ""
},
"channels": [
{ "type": "email", "target": "security@example.com", "secret": "", "has_secret": false },
{ "type": "webhook", "target": "https://hooks.example.com/activity", "secret": "••••cret", "has_secret": true }
],
"throttle_minutes": 15,
"created_by": 1,
"created_at": "2026-11-12 09:30:00",
"modified_at": "2026-11-12 09:30:00"
}
}
| Field | Type | Meaning |
|---|---|---|
data.id |
integer |
The new rule’s id |
data.conditions |
object |
The conditions as stored, every key present |
data.channels[].secret |
string |
Masked: four dots and the last four characters |
data.channels[].has_secret |
boolean |
Whether a signing secret is stored |
data.created_by |
integer |
Your WordPress user id |
data.created_at |
string |
UTC datetime |
Errors
| Status | Code | When |
|---|---|---|
422 |
plugixa_activity_log_invalid |
name is blank, no usable channel is left, or an email channel’s address is not valid. |
422 |
plugixa_activity_log_unsafe_url |
A channel’s address is not a valid URL, does not use https://, or points at this machine or a private network. |
500 |
plugixa_activity_log_save_failed |
The rule could not be saved. |
Plus the errors every endpoint can return.
Examples
curl -s -X POST "https://your-site.example/wp-json/plugixa-activity-log/v1/rules" \
-u "admin:$WP_APP_PASSWORD" \
-H "Content-Type: application/json" \
-d '{"name":"Administrator sign-ins from outside the office","conditions":{"groups":["authentication"],"min_severity":"medium","user_roles":["administrator"],"ips":["203.0.113.0/24"]},"channels":[{"type":"email","target":"security@example.com"},{"type":"webhook","target":"https://hooks.example.com/activity","secret":"a-signing-secret"}],"throttle_minutes":15}'
<?php
$ch = curl_init('https://your-site.example/wp-json/plugixa-activity-log/v1/rules');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => 'admin:' . getenv('WP_APP_PASSWORD'),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Administrator sign-ins from outside the office',
'conditions' => [
'groups' => ['authentication'],
'min_severity' => 'medium',
'user_roles' => ['administrator'],
'ips' => ['203.0.113.0/24'],
],
'channels' => [
['type' => 'email', 'target' => 'security@example.com'],
['type' => 'webhook', 'target' => 'https://hooks.example.com/activity', 'secret' => 'a-signing-secret'],
],
'throttle_minutes' => 15,
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const auth = Buffer.from(`admin:${process.env.WP_APP_PASSWORD}`).toString('base64');
const response = await fetch('https://your-site.example/wp-json/plugixa-activity-log/v1/rules', {
method: 'POST',
headers: {
'Authorization': `Basic ${auth}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Administrator sign-ins from outside the office',
conditions: {
groups: ['authentication'],
min_severity: 'medium',
user_roles: ['administrator'],
ips: ['203.0.113.0/24'],
},
channels: [
{ type: 'email', target: 'security@example.com' },
{ type: 'webhook', target: 'https://hooks.example.com/activity', secret: 'a-signing-secret' },
],
throttle_minutes: 15,
}),
});
const { data } = await response.json();
Quick Links
Share