Skip to main content
Version: v5.6.1

Event

Included from Basic tier

An event is one row of the append-only audit/operational spine: everything a run, a runner, a trigger or an operator does lands here, and the triage flow (opschain events → opschain chains triage) reads it back. JSON:API type: event.

The v2 OpenAPI document declares this resource's schema; the resource-field coverage gate holds this page to it.

Endpoints​

RouteServes
GET /api/eventsList, created_at desc then id desc by default. Default limit 10, max 1000; 206 + meta.partial_response when trimmed.
GET /api/events/{id}Show.

List meta carries authorisations.update on /events and partial_response.

The database read is bounded by the request: the server fetches limit+1 rows (the one extra detects truncation for the 206), never more than 1001 — so a polled page costs a page-sized read, not a cap-sized one.

Attributes​

The attribute object is the fixed attributes plus the event payload's own keys spread beside them (the payload is the event's stored data document — e.g. message, error, reason, whatever the emitter recorded). Payload keys are filterable alongside the fixed columns — see Filters.

AttributeTypeMeaning / origin / null semantics
typestringThe colon-namespaced event type — grammar below.
usernamestring/nullThe acting principal, recorded at write time for every principal-initiated event (run create/retry, approve/reject/continue, cancel, pause/resume, the admin and governance verbs); the stored column serialized as-is, so null on genuinely system-initiated rows — an engine roll-up carries no actor by meaning (never coerced to "").
systembooleanTrue for system-emitted audit events (the step/run transition audits), false for user-emitted ones.
event_node_pathstring/nullThe node path the event is about; null when not node-scoped.
created_atstringWhen the event was appended (ISO8601, six fractional digits).
correlation_idstringThe chain handle; defaults to the event's own id when the row stores none.
chain_depthintegerHops from the chain's origin.
payload keysanyThe event's data keys, spread verbatim beside the fixed attributes. Absent when the payload lacks them.
actorobjectThe audit envelope of the request that caused the event (opschain docs events, "The audit envelope"): principal_id (the acting user's id), session_id for a native session or token_id + token_kind for any other credential, client_address (resolved behind any trusted proxy), user_agent and request_id — each key present only when known, never a username or email. Absent on engine-originated events.

The type grammar​

type is colon-namespaced, three segments: a root (a severity or family), an area (the subject domain, plural), and a verb (what happened) — <root>:<area>:<verb>. Roots in use:

  • api: — run/step lifecycle facts. The chain-triage matcher names the full verb set: api:(changes|workflow_runs|steps):(create|start|success|error| system_error|abort|cancel|retry|child_complete|child_failed| pre_execution) (e.g. api:steps:success, api:changes:create). Since the root also carries the generic mutation audit (upstream's around_action :track_event): every tracked v1 POST/PATCH/PUT/DELETE answering 2xx records api:<controller>:<action> with the acting username, the request's data.attributes (request_body) and URL params (url_params), and the written model as the source — api:projects:create|update|destroy for projects, api:nodes:create|update|destroy for every other node kind, plus templates, template versions, git remotes, workflows/versions, authorisation management, properties, settings, scheduled activities (api:scheduled_workflows:*/api:scheduled_changes:*) and the run/step verbs. Lanes with their own events (run creation, artefact create, maintenance, licence, node_background_tasks create) are not doubled; the secrets endpoints emit nothing (their store_file lane is multipart); the embedded (SQLite) store has no event writer, so it records none of these. The recorded request data is masked before storage — credential-shaped attribute/parameter names (password, passphrase, secret, token, api_key, private_key, ssh_key, credential, vault_value, value_to_encrypt) store {{hidden}}, git_remotes events additionally mask user, and URL userinfo sanitises to ://hidden@ — because events are customer-visible egress.
  • audit: — attributable user actions, e.g. audit:steps:approve, audit:steps:reject, audit:steps:continue, audit:steps:cancel, audit:changes:pause, audit:changes:resume, audit:workflow_runs:pause, audit:workflow_runs:resume. These are what the run serializers fold into approved_by/rejected_by/paused_by.
  • info: / warn: / error: — operational severities, e.g. info:runner:registered, info:runner:drain_changed, warn:runner:aged_out, warn:runner:fleet_drained (the dispatch plane's vocabulary — opschain docs fleet-queue lists it in full).

The CLI's --errors filter defines "error-ish" as the error:/warn: prefixes plus the :error/:system_error/:pre_execution suffixes.

Filters​

Events are the first list on the shared Ransack grammar (fail-closed: an unknown predicate or sort is a 400, never silently dropped). Filterable attributes: the fixed columns type, username, system (compared as text "true"/"false"), event_node_path, created_at, id — plus any payload field (the upstream dynamic data->> ransackers): an attribute outside the fixed columns filters the payload key of that name as its text rendering (booleans as "true"/"false", an absent key or json null matching nothing), and the request_body_/url_params_ prefixes address fields of those nested payload objects — e.g. filter[template_version_id_eq]=…, filter[in_progress_eq]=true. Predicates: eq, not_eq, gt, gteq, lt, lteq, cont, not_cont, cont_any, start, end, in, not_in, present, blank, null, true, false — e.g. filter[type_start]=audit:, filter[created_at_gteq]=…, filter[username_in][]=…. The cont family matches case-insensitively with LIKE metacharacters in the term taken literally (upstream's escaped-wildcard ILIKE); start stays a byte-wise prefix test. Grouped predicate sets combine with filter[g][][m]=and|or; sorts with filter[sorts][]=created_at desc (sortable: created_at, id).

One ransackable scope is special-cased: filter[for_change]=<change id> — the change's own events plus its steps' events (source_type Change or BaseStep). A non-UUID value is a 400 invalid value for for_change: must be a change id.

The v2 EventFilter (EventService.ListEvents / WatchEvents / GetEventStats, opschain docs api-v2) is the typed form of the same vocabulary. Its type narrowing has three shapes: types (exact, any-of), type_prefixes (the type starts with the prefix, any-of with types) and type_search — the type contains every term, case-insensitively, anywhere: agent finds warn:agent:halted and info:agent:request alike, agent halt needs both words, and a term may carry : (agent:halt). type_search combines with AND against the other two. The server resolves the terms against the catalogue of event types (the registered types plus those stored, refreshed every 30 seconds) and filters on the exact matches through the type index, so a contains search never scans the history; terms no type contains list nothing. The GUI's audit history search box and opschain audit --type-search send it.

The source relationship and include=​

Every event carries a source relationship whose links.source is the source's API URL (/api/changes/{id}, /api/steps/{id}, /api/workflow_runs/{id}, /api/workflow_steps/{id}), null when the event has no linkable source. Resource-identifier data appears only when the request includes the source (include=source, or any source.-prefixed path) — the upstream serializer's lazy-load posture. Workflow-step sources carry their STI wire type (e.g. workflow_change_step); an unlinked or unresolvable source serializes data: null. With the include, the compound document carries the resolved change/step/run/workflow-step resources, and dotted paths walk onward (e.g. include=source.change).

Subscriptions​

Events feed the notification pipeline: a v2 NotificationService subscription selects events with the selector grammar and delivers them through its routes (opschain docs resources/notification; the v1 event_filters/event_subscribers families are removed). Triggers also consume events (caused_by_event_id on the runs they fire — opschain docs triggers).

  • opschain docs cli/events — the CLI view, watching and triage entry point.
  • opschain docs fleet-queue — the runner plane's event vocabulary.
  • opschain docs resources/change, opschain docs resources/step — where the audit events surface as attributes.