> ## Event sets

> Fetch the complete documentation index at: https://antithesis.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---

The event search API endpoint provides you a programmatic way to query the events recorded during a test run. You describe the events you want using "event sets", send it to the API, and get back the matching events as NDJSON.

The event sets used in the event search request are conceptually the same as those in [Querying with event sets](/docs/product/debugging/advanced_multiverse_debugging/event_sets/) but are used slightly differently. This is a reference for constructing event sets for the event search request.

## What is an event set

An **event set** is a query over the events Antithesis recorded during a test run. Event sets are a pipeline of operations separated by a `.`, applied left to right to the underlying event stream. These operations are called "verbs".

Let's look at a simple example of an event set before looking at all available verbs for creating an event set.

### Example

Imagine you ran a test run with 5 containers in your system, and you want to get the first two events from a specific conatiner in your system. Here's how you'd construct the request body to fetch exactly what you want:

```json
{
  "query": "matches({container: \"fdb-workload-1\"})", 
  "limit": 2,
}
```

The API responds with **NDJSON** of [`Event`](#event) objects:

```json
{"moment":{"input_hash":"4536913169440939055","vtime":"750.6794897380751"},"AtomicMutations":"0 -1 0","BatchPriorityReadVersions":"0 -1 0","BatchPriorityReadVersionsCompleted":"0 -1 0","BlobGranuleLocationRequests":"0 -1 0","BlobGranuleLocationRequestsCompleted":"0 -1 0","BytesRead":"0 -1 0","ClearMutations":"0 -1 0","ClientDescription":"external-7.3.75-2083768936062727749","Cluster":"docker","CommitCompleted":"0 -1 0","CommitStarted":"0 -1 3","CommitVersionNotFoundForSS":"0 -1 0","CommittedMutationBytes":"0 -1 0","CommittedMutations":"0 -1 0","DateTime":"2026-07-02T01:53:41Z","DefaultPriorityReadVersions":"0 -1 3","DefaultPriorityReadVersionsCompleted":"0 -1 0","Elapsed":"6.56977","ExpensiveClearCostEstCount":"0 -1 0","FutureVersions":"0 -1 0","GetAddressesForKeyRequests":"0 -1 0","GetKeyRequests":"0 -1 0","GetMappedRangeRequests":"0 -1 0","GetRangeRequests":"0 -1 0","GetRangeStreamRequests":"0 -1 0","GetValueRequests":"0 -1 0","ID":"088520088d239923","IPT_bytes_out":1023814952,"ImmediatePriorityReadVersions":"0 -1 0","ImmediatePriorityReadVersionsCompleted":"0 -1 0","Internal":"0","KeyServerLocationRequests":"0 -1 0","KeyServerLocationRequestsCompleted":"0 -1 0","KeysRead":"0 -1 0","Latency90":"0","Latency98":"0","LocationCacheEntryCount":"1","LogGroup":"default","LogicalUncachedReads":"0 -1 0","Machine":"10.89.0.6:80","MaxBytesPerCommit":"-1.79769e+308","MaxCommitLatency":"-1.79769e+308","MaxGRVLatency":"-1.79769e+308","MaxLatency":"-1.79769e+308","MaxMutationsPerCommit":"-1.79769e+308","MaxRowReadLatency":"-1.79769e+308","MaybeCommitted":"0 -1 0","MeanBytesPerCommit":"0","MeanCommitLatency":"0","MeanGRVLatency":"0","MeanLatency":"0","MeanMutationsPerCommit":"0","MeanRowReadLatency":"0","MedianBytesPerCommit":"0","MedianCommitLatency":"0","MedianGRVLatency":"0","MedianLatency":"0","MedianMutationsPerCommit":"0","MedianRowReadLatency":"0","MetadataVersionReads":"0 -1 0","NotCommitted":"0 -1 0","NumGrvFullBatches":"0 -1 0","NumGrvTimedOutBatches":"0 -1 3","NumLocalityCacheEntries":"1","OutstandingWatches":"0","PhysicalReadRequests":"0 -1 0","PhysicalReadRequestsCompleted":"0 -1 0","ProcessBehind":"0 -1 0","ReadVersionBatches":"0 -1 3","ReadVersions":"0 -1 3","ReadVersionsCompleted":"0 -1 0","ReadVersionsThrottled":"0 -1 0","ResourceConstrained":"0 -1 0","SetMutations":"0 -1 3","Severity":"10","StatusRequests":"0 -1 8","TenantLookupRequests":"0 -1 0","TenantLookupRequestsCompleted":"0 -1 0","ThreadID":"13587819877422497627","Throttled":"0 -1 0","Time":"1782957221.228375","TooOld":"0 -1 0","Type":"TransactionMetrics","WatchMapSize":"0","WatchRequests":"0 -1 0","source":{"container":"fdb-workload-1","name":"antithesis/pods/fdb-workload-1/trace.10.89.0.6.80.1782956528.pdw76G.0.2.json","pid":85}}
{"moment":{"input_hash":"6572773276055372305","vtime":"503.44814017694443"},"ClientDescription":"external-7.1.67-1285091599831140879","DateTime":"2026-07-02T01:49:51Z","ID":"0000000000000000","IPT_bytes_out":182368408,"LogGroup":"default","Machine":"10.89.0.6:139","PeerAddr":"10.89.0.9:4500(fromHostname)","Severity":"10","SuppressedEventCount":"6","ThreadID":"1285091599831140879","Time":"1782956991.856739","Type":"ConnectionTimedOut","source":{"container":"fdb-workload-1","name":"antithesis/pods/fdb-workload-1/trace.10.89.0.6.139.1782956560.xcUgXo.0.1.json","pid":195}}
```

Key points about the response:

- Each event carries a `moment` field that identifies **when** the event happened within the run. Specifically, `vtime` identifies the time of event.
- At most `limit` events are returned.

## Verbs

These are all the operations you can request in the API query. All of these operations can be chained together by a `.` and are evaluated left to right.

#### matches

Filter events whose fields exactly match the given values.

```javascript
matches({field_1: "exact value 1", field_2: "exact value 2", ...})
```

#### contains

Filter events whose fields contain the given substrings.

```javascript
contains({field_1: "substring 1", field_2: "substring 2", ...})
```

#### not\_matches

Exclude events whose fields exactly match the given values.

```javascript
not_matches({field_1: "exact value 1", field_2: "exact value 2", ...})
```

#### excludes

Exclude events whose fields contain the given substrings.

```javascript
excludes({field_1: "substring 1", field_2: "substring 2", ...})
```

#### map

Transforms the event fields as per the given expression.

```javascript
map(row => expr)
```

#### filter

Filter events where the predicate is truthy.

```javascript
filter(row => expr)
```

To filter events with vtime after 20:

```javascript
filter((event) => event.moment.vtime > 20)
```

#### flatmap

Transform and flatten the result by one level.

```javascript
flatmap(row => expr)
```

#### fold

A higher-order function that processes a complex data structure and iteratively computes a set of values to attach to each event.

```javascript
fold((state, event) => expr, initial_state)
```

#### narrow

Restrict events to the listed fields (plus a small set of fields that can't be dropped).

```javascript
narrow(["field1", "field2"])
```

#### union

Takes arbitrarily many event sets and performs a logical OR on all of them. This operation will deduplicate events with the same fields and same values.

```javascript
union(pipeline, pipeline, ...)
```

When you want events from either container A or container B:

```javascript
union(matches({container: "con-A"}), matches({container: "con-B"}))
```

#### intersect

Takes arbitrarily many event sets and performs a logical AND on all of them.

```javascript
intersect(pipeline, pipeline, ...)
```

when you want only the error events from a specific container:

```javascript
intersect(matches({container: "con-A"}), filter((event) => event.stream == "error"))
```

#### difference

Takes arbitrarily many event sets and performs a logical XOR on all of them. It'll remove the events that are common between the supplied events sets.

```javascript
difference(pipeline, ...)
```

#### distinct\_by\_moment

Takes arbitrarily many event sets and performs a union but deduplicates events by only the `moment` field.

```javascript
distinct_by_moment(pipeline, ...)
```

#### with\_last

Annotates each event in the caller event set with additional fields. For each event, it'll look back at it's own execution history to find the closest event that's in the named event sets supplied in the arguments. If multiple named event sets are supplied in the arguments, it'll add a field for each named argument. The added field is `last_{name}`, where `{name}` is the label of the event sent supplied in the arguments.

```javascript
with_last({name: pipeline, ...})
```

#### with\_next

Annotates each event in the event sets supplied in the arguments with additional fields. For each event in the caller event set, it'll look ahead at the events in the timeline after itself to find the closest event that's in the named event sets supplied in the arguments. If multiple named event sets are supplied in the arguments, it'll find the next event in any of the named event sets. The look-ahead can be bounded by passing a timeout in the arguments. If the timeout is set to 10, the fields are set only if there is a match within 10 seconds after the event itself. This operation adds two fields, `last_event` which is the caller event, and `with_next_type` which is the label of the named event set it belongs to.

```javascript
with_next({name: pipeline, ...}, timeout_sec)
```

## Event

An event represents anything that happened within the simulation.

### Event emitters

The following will emit events:

- **stdout/stderr**: Standard output of processes inside your containers will emit events
- **SDK events**: Our SDK assertions communicate with the rest of our system using events. You may also generate custom events using the SDK's `send_event()` method.
- **SDK capture directory**: Files written to a [special location](/docs/configuration/the_antithesis_environment/#capturing-output) will emit events.
- **Antithesis environment**: Systems like our fault injector, journald, and others will emit events. See [their documentation](/docs/product/debugging/advanced_multiverse_debugging/bash_env/#environment-event-sets) for details.

### Event fields

Events have the following fields (optional where noted):

- `event.moment`: The [moment](/docs/product/debugging/advanced_multiverse_debugging/moment_branch/#core-concepts) at which an event happened.
- `event.moment.vtime`: The time that passed within the simulation along this timeline, measured in seconds.
- `event.source`: The source that emitted an event.
- `event.source.name`: The human-readable name of the system or process that emitted the event.

  - For `stdout`/`stderr`  and SDK assertion events it is your container name.
  - For the SDK capture directory, it is effectively the path into that directory and is [documented here](/docs/configuration/the_antithesis_environment/#capturing-output).
  - For [Environment event emitters](/docs/product/debugging/advanced_multiverse_debugging/bash_env/#environment-event-sets) `fault_injector`, `journal`, and `background_monitor` it is the that emitter name.
- `event.source.pid`: Optional. The Linux process ID of the process that generated this event. PIDs are available for events emitted by the Antithesis SDK, or via writes to the SDK capture directory.
- `event.source.container`: Optional. The hostname of the container that generates this event, if any.
- `event.source.stream`: Optional. Current values include `"error"`, `"info"`, `"internal"`. For `stdout`/`stderr`  this maps to `"info"` and `"error"` respectively.
- `event.output_text`: Optional. The text-payload of the event. For `stdout` events this will be the verbatim text, with one event per newline.
- `event.exit_code`: Optional. If present, means that the Antithesis environment has terminated with an exit code. This is an error in the Antithesis platform, please email `support@antithesis.com` to let us know.
