Security events

Query the security events of a zone, with filters, summaries, histograms and a live Server-Sent Events stream.

On this page

Security events are the requests the edge blocked, challenged or logged (WAF, rules, rate limits, shields). All endpoints share the same filters; every filter can be repeated and different filters combine with AND.

OperationEndpoint
List eventsGET /v1/orgs/{org}/zones/{zone}/events
Summarize eventsGET /v1/orgs/{org}/zones/{zone}/events/summary
Events histogramGET /v1/orgs/{org}/zones/{zone}/events/histogram
Stream eventsGET /v1/orgs/{org}/zones/{zone}/events/stream

List events

GET /v1/orgs/{org}/zones/{zone}/events

Lists the security events of the zone, newest first. Every filter can be repeated (action=block&action=log matches any of the values) with at most 20 values; different filters combine with AND, and the not_… filters exclude events with any of their values. q searches text (case-insensitive) in host, path, IP, method, rule, attack type, message, user agent, country, rule id and status. Page with cursor set to next_cursor.

Required role: readonly or higher.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).
zonepathstring (uuid)YesZone id (see List zones).
sincequerystring (date-time)NoRFC 3339; until minus 24 hours by default.
untilquerystring (date-time)NoRFC 3339, exclusive; now by default. At most 31 days of range.
actionquerystringNoRepeatable (any of the values, at most 20). One of block, log, challenge, allow.
rule_idqueryintegerNoRepeatable. From 0 to 4294967295.
ipquerystringNoIPv4 or IPv6 (normalized); repeatable.
countryquerystringNoISO 3166-1 alpha-2 (lowercase accepted); repeatable. Pattern ^[A-Za-z]{2}$.
hostquerystringNoExact name (case-insensitive); repeatable. 1 to 253 characters.
pathquerystringNoExact path (1-2048 bytes); repeatable. 1 to 2048 characters.
statusqueryintegerNoHTTP status of the response; repeatable. From 100 to 599.
rate_rulequerystringNoEvents of that rate limiting rule (rule_name rate_rule:<id>, attack_type rate_limit); repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
rule_namequerystringNoExact rule_name (the code of an egress block, e.g. injection_detected); repeatable. 1 to 200 characters.
not_actionquerystringNoExcludes those actions; repeatable. One of block, log, challenge, allow.
not_rule_idqueryintegerNoExcludes those rules; repeatable. From 0 to 4294967295.
not_ipquerystringNoExcludes those IPs; repeatable.
not_countryquerystringNoExcludes those countries; repeatable. Pattern ^[A-Za-z]{2}$.
not_hostquerystringNoExcludes those names; repeatable. 1 to 253 characters.
not_pathquerystringNoExcludes those exact paths; repeatable. 1 to 2048 characters.
not_statusqueryintegerNoExcludes those HTTP statuses; repeatable. From 100 to 599.
not_rate_rulequerystringNoExcludes the events of those rate limiting rules; repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
not_rule_namequerystringNoExcludes those rule_name values; repeatable. 1 to 200 characters.
qquerystringNoFree text (case-insensitive) in host, path, IP, method, rule_name, attack_type, msg, user agent, country, rule_id and status. At most 200 characters.
limitqueryintegerNoMaximum number of items. Default 100. From 1 to 1000.
cursorquerystringNonext_cursor of the previous page.

Response

  • 200: Returns an object with the fields below.
FieldTypeDescription
itemsarray of EdgeEvent
next_cursorstring

Errors

StatusDescription
400Malformed request (bad_request).
404Not found, or not visible to the token (not_found).
503Not available right now (unavailable); retry later.

Example

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/events?action=block&limit=50" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "items": [
    {
      "event_id": "8b3e5f7a-1c2d-4e6f-9a0b-3c5d7e9f1a2b",
      "zone_id": "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
      "node_id": "edge-node",
      "ts": "2026-10-27T09:29:58Z",
      "host": "www.example.com",
      "ip": "203.0.113.10",
      "method": "POST",
      "path": "/login",
      "status": 429,
      "action": "block",
      "rule_id": 0,
      "rule_name": "rate_rule:login",
      "attack_type": "rate_limit",
      "msg": "",
      "country_code": "ES",
      "asn": 64500,
      "user_agent": "Mozilla/5.0",
      "tls_fingerprint": "",
      "received_at": "2026-10-27T09:29:59Z",
      "rate_rule": "login"
    }
  ],
  "next_cursor": ""
}

Summarize events

GET /v1/orgs/{org}/zones/{zone}/events/summary

Counts the events that match the filters (the same as List events) by action, with the 10 rules, the 10 countries and the 10 rate limiting rules with most events.

Required role: readonly or higher.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).
zonepathstring (uuid)YesZone id (see List zones).
sincequerystring (date-time)NoRFC 3339; until minus 24 hours by default.
untilquerystring (date-time)NoRFC 3339, exclusive; now by default. At most 31 days of range.
actionquerystringNoRepeatable (any of the values, at most 20). One of block, log, challenge, allow.
rule_idqueryintegerNoRepeatable. From 0 to 4294967295.
ipquerystringNoIPv4 or IPv6 (normalized); repeatable.
countryquerystringNoISO 3166-1 alpha-2 (lowercase accepted); repeatable. Pattern ^[A-Za-z]{2}$.
hostquerystringNoExact name (case-insensitive); repeatable. 1 to 253 characters.
pathquerystringNoExact path (1-2048 bytes); repeatable. 1 to 2048 characters.
statusqueryintegerNoHTTP status of the response; repeatable. From 100 to 599.
rate_rulequerystringNoEvents of that rate limiting rule (rule_name rate_rule:<id>, attack_type rate_limit); repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
rule_namequerystringNoExact rule_name (the code of an egress block, e.g. injection_detected); repeatable. 1 to 200 characters.
not_actionquerystringNoExcludes those actions; repeatable. One of block, log, challenge, allow.
not_rule_idqueryintegerNoExcludes those rules; repeatable. From 0 to 4294967295.
not_ipquerystringNoExcludes those IPs; repeatable.
not_countryquerystringNoExcludes those countries; repeatable. Pattern ^[A-Za-z]{2}$.
not_hostquerystringNoExcludes those names; repeatable. 1 to 253 characters.
not_pathquerystringNoExcludes those exact paths; repeatable. 1 to 2048 characters.
not_statusqueryintegerNoExcludes those HTTP statuses; repeatable. From 100 to 599.
not_rate_rulequerystringNoExcludes the events of those rate limiting rules; repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
not_rule_namequerystringNoExcludes those rule_name values; repeatable. 1 to 200 characters.
qquerystringNoFree text (case-insensitive) in host, path, IP, method, rule_name, attack_type, msg, user agent, country, rule_id and status. At most 200 characters.

Response

  • 200: Returns an object with the fields below.
FieldTypeDescription
sincestring (date-time)
untilstring (date-time)
totalinteger
by_actionarray of KeyCount
top_rulesarray of object
top_rules[].rule_idintegerId of the rule.
top_rules[].rule_namestringName or code of the rule.
top_rules[].countinteger
top_countriesarray of KeyCount
top_rate_rulesarray of KeyCountEvents of rate limiting rules per rule id (key).

Errors

StatusDescription
400Malformed request (bad_request).
404Not found, or not visible to the token (not_found).
503Not available right now (unavailable); retry later.

Example

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/events/summary" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "since": "2026-10-27T09:30:00Z",
  "until": "2026-10-27T09:30:00Z",
  "total": 128,
  "by_action": [
    {
      "key": "/pricing",
      "count": 128
    }
  ],
  "top_rules": [
    {
      "rule_id": 0,
      "rule_name": "example",
      "count": 128
    }
  ],
  "top_countries": [
    {
      "key": "/pricing",
      "count": 128
    }
  ],
  "top_rate_rules": [
    {
      "key": "/pricing",
      "count": 128
    }
  ]
}

Events histogram

GET /v1/orgs/{org}/zones/{zone}/events/histogram

Counts the events that match the filters per time interval and action. Bars of step seconds are aligned to multiples of step since the Unix epoch, with no gaps (empty bars count 0); the first one contains since and the last one starts before until.

Required role: readonly or higher.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).
zonepathstring (uuid)YesZone id (see List zones).
sincequerystring (date-time)NoRFC 3339; until minus 24 hours by default.
untilquerystring (date-time)NoRFC 3339, exclusive; now by default. At most 31 days of range.
stepqueryintegerNoSeconds per bar (1-86400). By default the smallest of 1, 5, 10, 15, 30, 60, 120, 300, 600, 900, 1800, 3600, 10800, 21600, 43200 and 86400 that gives at most 60 bars; with an explicit step, more than 1000 bars answers 400. From 1 to 86400.
actionquerystringNoRepeatable (any of the values, at most 20). One of block, log, challenge, allow.
rule_idqueryintegerNoRepeatable. From 0 to 4294967295.
ipquerystringNoIPv4 or IPv6 (normalized); repeatable.
countryquerystringNoISO 3166-1 alpha-2 (lowercase accepted); repeatable. Pattern ^[A-Za-z]{2}$.
hostquerystringNoExact name (case-insensitive); repeatable. 1 to 253 characters.
pathquerystringNoExact path (1-2048 bytes); repeatable. 1 to 2048 characters.
statusqueryintegerNoHTTP status of the response; repeatable. From 100 to 599.
rate_rulequerystringNoEvents of that rate limiting rule (rule_name rate_rule:<id>, attack_type rate_limit); repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
rule_namequerystringNoExact rule_name (the code of an egress block, e.g. injection_detected); repeatable. 1 to 200 characters.
not_actionquerystringNoExcludes those actions; repeatable. One of block, log, challenge, allow.
not_rule_idqueryintegerNoExcludes those rules; repeatable. From 0 to 4294967295.
not_ipquerystringNoExcludes those IPs; repeatable.
not_countryquerystringNoExcludes those countries; repeatable. Pattern ^[A-Za-z]{2}$.
not_hostquerystringNoExcludes those names; repeatable. 1 to 253 characters.
not_pathquerystringNoExcludes those exact paths; repeatable. 1 to 2048 characters.
not_statusqueryintegerNoExcludes those HTTP statuses; repeatable. From 100 to 599.
not_rate_rulequerystringNoExcludes the events of those rate limiting rules; repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
not_rule_namequerystringNoExcludes those rule_name values; repeatable. 1 to 200 characters.
qquerystringNoFree text (case-insensitive) in host, path, IP, method, rule_name, attack_type, msg, user agent, country, rule_id and status. At most 200 characters.

Response

FieldTypeDescription
sincestring (date-time)
untilstring (date-time)
stepintegerSeconds per bar.
totalintegerEvents in [since, until).
bucketsarray of object
buckets[].tsstring (date-time)Start of the bar.
buckets[].countinteger
buckets[].blockinteger
buckets[].loginteger
buckets[].challengeinteger
buckets[].allowinteger

Errors

StatusDescription
400Malformed request (bad_request).
404Not found, or not visible to the token (not_found).
503Not available right now (unavailable); retry later.

Example

curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/events/histogram" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
{
  "since": "2026-10-27T09:30:00Z",
  "until": "2026-10-27T09:30:00Z",
  "step": 0,
  "total": 128,
  "buckets": [
    {
      "ts": "2026-10-27T09:30:00Z",
      "count": 128,
      "block": 0,
      "log": 0,
      "challenge": 0,
      "allow": 0
    }
  ]
}

Stream events

GET /v1/orgs/{org}/zones/{zone}/events/stream

Streams the zone's events that match the filters (the same as List events; since, until and limit are not used) as Server-Sent Events, in the order OpenWAF receives them. Authentication, zone and filters are checked before the stream starts, so errors are JSON answers.

The stream starts after Last-Event-ID (sent by EventSource when it reconnects) or cursor; without them, 10 seconds before the request. Load GET …/events first and drop repeated event_id values. Frames:

  • event: ready first, with {"poll_ms": 2000, "heartbeat_ms": 15000, "max_age_s": 600}.
  • event: event for each event, with its cursor in id and the event in data (as in List events).
  • event: ping after heartbeat_ms without traffic, to detect hung connections.
  • event: bye after max_age_s, then the stream closes; EventSource reconnects with Last-Event-ID without losing events.
  • event: error with {"code": "unavailable"} if the event store fails, then the stream closes.

An event received more than an hour after it happened is not streamed (it is listed by List events). At most 10 streams per organization.

Required role: readonly or higher.

Parameters

NameInTypeRequiredDescription
orgpathstring (uuid)YesOrganization id. Every route checks that it is the token's organization (otherwise 404).
zonepathstring (uuid)YesZone id (see List zones).
Last-Event-IDheaderstringNoid of the last event received from a stream (sent by EventSource when it reconnects); takes precedence over cursor.
cursorquerystringNoid of an event of a previous stream: starts right after it.
actionquerystringNoRepeatable (any of the values, at most 20). One of block, log, challenge, allow.
rule_idqueryintegerNoRepeatable. From 0 to 4294967295.
ipquerystringNoIPv4 or IPv6 (normalized); repeatable.
countryquerystringNoISO 3166-1 alpha-2 (lowercase accepted); repeatable. Pattern ^[A-Za-z]{2}$.
hostquerystringNoExact name (case-insensitive); repeatable. 1 to 253 characters.
pathquerystringNoExact path (1-2048 bytes); repeatable. 1 to 2048 characters.
statusqueryintegerNoHTTP status of the response; repeatable. From 100 to 599.
rate_rulequerystringNoEvents of that rate limiting rule (rule_name rate_rule:<id>, attack_type rate_limit); repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
rule_namequerystringNoExact rule_name (the code of an egress block, e.g. injection_detected); repeatable. 1 to 200 characters.
not_actionquerystringNoExcludes those actions; repeatable. One of block, log, challenge, allow.
not_rule_idqueryintegerNoExcludes those rules; repeatable. From 0 to 4294967295.
not_ipquerystringNoExcludes those IPs; repeatable.
not_countryquerystringNoExcludes those countries; repeatable. Pattern ^[A-Za-z]{2}$.
not_hostquerystringNoExcludes those names; repeatable. 1 to 253 characters.
not_pathquerystringNoExcludes those exact paths; repeatable. 1 to 2048 characters.
not_statusqueryintegerNoExcludes those HTTP statuses; repeatable. From 100 to 599.
not_rate_rulequerystringNoExcludes the events of those rate limiting rules; repeatable. Pattern ^[a-z0-9][a-z0-9-]{0,39}$.
not_rule_namequerystringNoExcludes those rule_name values; repeatable. 1 to 200 characters.
qquerystringNoFree text (case-insensitive) in host, path, IP, method, rule_name, attack_type, msg, user agent, country, rule_id and status. At most 200 characters.

Response

  • 200: Server-Sent Events stream (frames described above). Body of type text/event-stream.

Errors

StatusDescription
400Malformed request (bad_request).
401Missing, invalid or expired token (unauthorized).
404Not found, or not visible to the token (not_found).
429too_many_streams: too many open streams in the organization; Retry-After in seconds.
503Not available right now (unavailable); retry later.

Example

Not in the SDKs: open the stream with EventSource or any Server-Sent Events client.

curl -N "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/events/stream?action=block" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
200
retry: 3000
event: ready
data: {"poll_ms":2000,"heartbeat_ms":15000,"max_age_s":600}

id: c2V0MTcz…
event: event
data: {"event_id":"…","action":"block","host":"www.example.com","path":"/wp-login.php","client_ip":"203.0.113.10"}

Last updated:

↑↓ to navigate↵ to openesc to close