This document explains how to query /events in this project.
Supported methods:
GET /eventswith query parametersPOST /eventswith a JSON body
/events returns a list named resources, where each item is the latest event for a resource (global_uid).
Internally, the query keeps only the newest row per global_uid, then applies filters, pagination, and ordering.
When available, each returned item also includes event_id, the identifier of
the underlying event row. The endpoint semantics do not change: /events still
returns the latest row per resource, not a full event feed.
All filters are optional and are combined with AND.
| Parameter | Type | Behavior |
|---|---|---|
cluster |
string | Exact match on cluster_name. |
namespace |
string | Exact match on namespace. |
kind |
string | Exact match on resource_kind. |
name |
string | Case-insensitive partial match on resource_name (ILIKE %name%). |
labels |
JSON object (string) | JSONB containment on raw->involvedObject->labels (@>). Must be valid JSON. |
since |
RFC3339 timestamp | Includes events with created_at >= since. |
limit |
integer | Page size. Default: 50. If <= 0, default 50 is used. |
cursor |
base64 string | Keyset cursor for pagination (opaque token returned by previous response). |
If since is invalid RFC3339 or labels is invalid JSON, the API returns 400.
If cursor is invalid base64/JSON, the API returns 400.
For POST /events, use the same fields in JSON format.
Example body:
{
"cluster": "cluster-a",
"namespace": "prod",
"kind": "Deployment",
"name": "api",
"labels": {
"app": "payments"
},
"since": "2026-03-01T00:00:00Z",
"limit": 100,
"cursor": "<cursor-from-previous-page>"
}Notes:
- Unknown JSON fields return
400. - Empty body returns
400. limitdefaults to50when omitted or<= 0.
curl "http://localhost:8083/events"curl --get "http://localhost:8083/events" \
--data-urlencode "cluster=cluster-a" \
--data-urlencode "namespace=default" \
--data-urlencode "kind=Pod"curl --get "http://localhost:8083/events" \
--data-urlencode "name=api"Matches names like api, API, my-api-service.
curl --get "http://localhost:8083/events" \
--data-urlencode 'labels={"app":"nginx","tier":"backend"}'labels uses JSON containment: all provided key/value pairs must exist in the resource labels.
curl --get "http://localhost:8083/events" \
--data-urlencode "since=2026-03-01T00:00:00Z"curl --get "http://localhost:8083/events" \
--data-urlencode "cluster=cluster-a" \
--data-urlencode "namespace=prod" \
--data-urlencode "kind=Deployment" \
--data-urlencode "name=api" \
--data-urlencode 'labels={"app":"payments"}' \
--data-urlencode "since=2026-03-01T00:00:00Z" \
--data-urlencode "limit=100"Use keyset pagination:
- First call without
cursor. - Read
cursorfrom response. - Send it back in the next call.
Example:
# page 1
curl --get "http://localhost:8083/events" \
--data-urlencode "limit=100"
# page 2
curl --get "http://localhost:8083/events" \
--data-urlencode "limit=100" \
--data-urlencode "cursor=<cursor-from-page-1>"The cursor is built from the last returned row (created_at, global_uid) and is opaque to clients.
Keep the same filters and limit, and only add/update cursor.
# first request
curl --get "http://localhost:8083/events" \
--data-urlencode "cluster=cluster-a" \
--data-urlencode "namespace=prod" \
--data-urlencode "kind=Deployment" \
--data-urlencode "limit=2"
# suppose response contains: "cursor": "<CURSOR_PAGE_1>"
# second request (same filters + cursor from page 1)
curl --get "http://localhost:8083/events" \
--data-urlencode "cluster=cluster-a" \
--data-urlencode "namespace=prod" \
--data-urlencode "kind=Deployment" \
--data-urlencode "limit=2" \
--data-urlencode "cursor=<CURSOR_PAGE_1>"
# third request uses cursor returned by page 2, and so onIf you change filters between pages, pagination continuity is broken.
This example keeps fetching pages until cursor is empty.
BASE_URL="http://localhost:8083/events"
CURSOR=""
while true; do
if [ -n "$CURSOR" ]; then
RESP=$(curl --silent --get "$BASE_URL" \
--data-urlencode "cluster=cluster-a" \
--data-urlencode "namespace=prod" \
--data-urlencode "kind=Deployment" \
--data-urlencode "limit=100" \
--data-urlencode "cursor=$CURSOR")
else
RESP=$(curl --silent --get "$BASE_URL" \
--data-urlencode "cluster=cluster-a" \
--data-urlencode "namespace=prod" \
--data-urlencode "kind=Deployment" \
--data-urlencode "limit=100")
fi
# process current page
echo "$RESP" | jq '.resources[]'
# read next cursor
CURSOR=$(echo "$RESP" | jq -r '.cursor // ""')
[ -z "$CURSOR" ] && break
doneKeep the same filters and limit, and only replace cursor.
# page 1
curl --silent --request POST "http://localhost:8083/events" \
--header "Content-Type: application/json" \
--data '{
"cluster":"cluster-a",
"namespace":"prod",
"kind":"Deployment",
"limit":2
}'
# page 2 (use cursor from page 1 response)
curl --silent --request POST "http://localhost:8083/events" \
--header "Content-Type: application/json" \
--data '{
"cluster":"cluster-a",
"namespace":"prod",
"kind":"Deployment",
"limit":2,
"cursor":"<CURSOR_PAGE_1>"
}'Sorting is implemented but not user-configurable.
Fixed order is:
created_at DESCglobal_uid DESC
There is no query parameter to change sort field or direction.