> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobhub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# blobhub workflow events

> List a session's event stream through the filter, or follow it as it grows

`events` reads a session's [event stream](https://docs.blobhub.io/blob-types/workflow/workflows/session-events.md): what was written, posted,
started and ended in it, in id order. It lists one page, or with `--follow` keeps printing new events until you stop
it.

It only reads. It never creates a session, and it works on a session of any status, a deleted one included while its
stream lasts.

## Synopsis

```bash theme={null}
blobhub workflow events <session> [--file <manifest>] [--types <glob>]... [--aliases <glob>]...
                        [--executions <id>]... [--listener <alias-or-id>] [--after <id-or-time>]
                        [--cursor <token>] [--limit <n>] [--follow]
```

| Flag | Default | Description |
| - | - | - |
| `<session>` | required | A session, or `<blob-id>/<revision>/<session>`, or `<org>/<blob>/<revision>/<session>`. See [The session argument](#the-session-argument). |
| `--file`, `-f` | none | Manifest naming the blob and revision of a bare session. Refused beside a qualified one. |
| `--types` | all types | Event types, globs allowed. Repeatable; each value may be a comma-separated list. |
| `--aliases` | all objects | Object aliases, globs allowed. Repeatable; each value may be a comma-separated list. |
| `--executions` | all executions | Execution ids. Repeatable; each value may be a comma-separated list. |
| `--listener` | none | Only the events a listener caused: its alias, or its definition id. |
| `--after` | none | List the events after this event id, boundary or ISO 8601 time. |
| `--cursor` | none | Continue a listing from the token it printed. Takes no other selector. |
| `--limit` | `20` | Events per page, from 1 to 1000. |
| `--follow` | off | Print new events as they arrive until interrupted. |

## The session argument

A session is named in one of three shapes, the
[workflow reference's path form](https://docs.blobhub.io/blob-types/workflow/workflows/workflow-reference.md#the-path-form) with a session last:

| Shape | Needs |
| - | - |
| `<session>` | `-f <manifest>`, whose `blob` and `revision` say where the session lives. |
| `<blob-id>/<revision>/<session>` | Nothing else. |
| `<org>/<blob>/<revision>/<session>` | Nothing else. |

`<revision>` is `default` or a revision id, and each part is at most 64 characters. A bare session beside no manifest,
a qualified one beside `-f`, and a malformed path are all `SESSION_REFERENCE_INVALID`, refused before any request.
A session that is absent or not reachable with the key is `SESSION_NOT_ACCESSIBLE`; the command never creates one.

The revision is read, not written, so a `commit`-phase revision works.

## Listing

Without `--follow`, `events` sends one `list_session_events` request and prints the page in id order:

* **Without `--after`** it prints the newest `--limit` events that match.
* **With `--after`** it prints the oldest `--limit` events after that point.

`--after` takes an event id, a bare boundary (sixteen hex digits and a dash), or an ISO 8601 time, which is read as
UTC when it has no zone and turned into the [boundary id](https://docs.blobhub.io/blob-types/workflow/workflows/session-events.md#boundary-ids)
of that instant. Anything else is `EVENT_FILTER_INVALID`.

```text theme={null}
2026-11-09T17:04:05.123456Z  thread.item_posted  missions/m-12/cells/c-3/meta intent  api 5f2c0a91-... client=web-7f3a
2026-11-09T17:04:06.004211Z  execution.created  7c1e0b52-...  listener listener=orchestrate
more: --cursor eyJhc2NlbmRpbmciOnRydWUs...
```

A line is the event's `created_at`, its `type`, its subject and who caused it. The subject is the object alias (with
the item's type for a thread item), the execution id (with its status for `execution.ended`), or the session's status.
*Who* is the source's `kind`, then the listener's alias for a listener's effect, the execution id for a run's write, or
the user id for an `api` write, and ` client=<tag>` when the source carries one. `-v` appends the event id.

Under `--json` the payload carries `session`, `events` and `cursor`, alongside the envelope's `schema_version`:

```json theme={null}
{"session": "my-session", "events": [{"id": "00065fdaf3076d80-7kq2m9zt", "type": "thread.item_posted"}], "cursor": null}
```

### The filter flags

`--types`, `--aliases` and `--executions` build the `types`, `aliases` and `executions` clauses of the
[event filter](https://docs.blobhub.io/blob-types/workflow/workflows/event-filter.md), and every clause present must hold. `--listener` adds a
`where` clause on `source.listener.alias`, or on `source.listener.definition_id` when the value is a canonical id, so it
selects the runs a listener started, their lifecycle events and every write they made.

The filter is checked in the CLI against the platform's grammar and bounds before anything is sent, and a breach is
`EVENT_FILTER_INVALID` naming the clause, as the platform words it. There is no flag for `where` or for a raw filter.

### Continuing a listing

A listing prints `more: --cursor <token>` when another page exists. The token is the CLI's own: it wraps the platform's
cursor together with the direction and the filter the page was read under, because the platform's cursor holds neither.
Pass it **alone**:

```bash theme={null}
# page two of whatever the first listing selected
blobhub workflow events <session> -f manifest.yaml --cursor <token>
```

`--cursor` beside `--after`, a filter flag or `--follow` is `EVENT_CURSOR_INVALID`, and so is a token this command did
not print. `--limit` may change between pages.

## Following

`--follow` polls every two seconds until you interrupt it. It does not open a WebSocket.

* **Without `--after`**, the first pass prints the newest `--limit` matches, then everything new.
* **With `--after`**, nothing is printed up front: it prints everything after that point, then everything new.
* **A late commit is not missed.** An event can become visible up to 60 seconds after the time in its id, so each pass
  re-reads about the last minute and drops what it already printed. An event that lands late is printed once, after
  events with larger ids. See [Settle time](https://docs.blobhub.io/blob-types/workflow/workflows/session-events.md#settle-time).
* **A quiet filter stays cheap.** Each pass re-reads about the last 60 seconds of the stream, not an ever-growing
  window.
* The command resolves the session once and follows it by id, so the stream of a session deleted mid-follow is still
  read.

It ends with exit `0` on Ctrl-C, even with a request in flight, and after printing a `session.deleted` event. A filter
that hides `session.deleted` does not hide the end: the follow notices it and stops. A session that stops resolving
mid-follow is `SESSION_NOT_ACCESSIBLE`.

Each event is flushed as it is printed, so it reaches a pipe at once:

```bash theme={null}
# events as JSON lines, one object per event
blobhub --json workflow events <session> -f manifest.yaml --follow | jq .event.type
```

Under `--json`, `--follow` writes **JSON Lines**: one `{"event": {...}, "schema_version": ...}` object per event, and
no final object, because a follow has no end to put one at.

The CLI sends no `client` tag on its own writes, so the events it causes carry none.

## Errors

| Code | When |
| - | - |
| `SESSION_REFERENCE_INVALID` | `<session>` is malformed, bare without `-f`, or qualified beside `-f`. |
| `SESSION_NOT_ACCESSIBLE` | The session is absent or not reachable with this key. |
| `EVENT_FILTER_INVALID` | A filter flag breaks the platform's grammar or bounds, or `--after` is not an id, a boundary or an ISO 8601 time. |
| `EVENT_CURSOR_INVALID` | `--cursor` is not a token this command printed, is combined with another selector, or the platform refused it. |
| `MANIFEST_NOT_FOUND`, `MANIFEST_INVALID`, `MANIFEST_TYPE_MISMATCH`, `MANIFEST_VERSION_UNSUPPORTED` | The manifest given with a bare session is absent or unusable. |
| `BLOB_NOT_ACCESSIBLE`, `BLOB_NOT_WORKFLOW`, `REVISION_NOT_ACCESSIBLE`, `REVISION_NOT_WRITABLE` | The blob or revision cannot be resolved, or its status is not `ready`. |
| `CREDENTIALS_NOT_FOUND`, `PROFILE_NOT_FOUND`, `INSECURE_CREDENTIALS_PERMISSIONS` | No usable credential, or a credentials file the CLI refuses to read. |
| `API_RATE_LIMITED`, `API_TRANSIENT_ERROR`, `API_NETWORK_ERROR` | A read failed after its retries. |

Every code above, with its remediation, is in [Error codes](https://docs.blobhub.io/cli/error-codes.md).

## See also

* [Session Events](https://docs.blobhub.io/blob-types/workflow/workflows/session-events.md) — the record, its source, the types and the settle
  time.
* [Event filter](https://docs.blobhub.io/blob-types/workflow/workflows/event-filter.md) — the clauses the flags build.
* [`blobhub workflow listeners`](https://docs.blobhub.io/cli/workflow/commands/listeners) — what the listeners of a session did.
* [`blobhub workflow execute`](https://docs.blobhub.io/cli/workflow/commands/execute) — `--watch` follows one run's log.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.