# network.bsky.jetstream.subscribeEvents

> Published by [bsky-lexicons.bsky.social](https://lexicon.garden/identity/did:plc:4v4y5r3lwsbtmsxhile2ljac)

✓ This is the authoritative definition for this NSID.

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:4v4y5r3lwsbtmsxhile2ljac/network.bsky.jetstream.subscribeEvents)
- [Documentation](https://lexicon.garden/lexicon/did:plc:4v4y5r3lwsbtmsxhile2ljac/network.bsky.jetstream.subscribeEvents/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:4v4y5r3lwsbtmsxhile2ljac/network.bsky.jetstream.subscribeEvents/examples)

## Definitions

### `network.bsky.jetstream.subscribeEvents#info`

**Type**: `object`

An advisory, non-fatal notice about the stream (mirrors com.atproto.sync.subscribeRepos#info). Carries no seq and does not advance the cursor. OutdatedCursor is sent as the first frame when a unix-microseconds timestamp cursor below the retention floor was clamped up to the floor; the message names the seq actually resumed from.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | `string` | Yes |  |
| `message` | `string` | No |  |

### `network.bsky.jetstream.subscribeEvents`

**Type**: `subscription`

Stream every archived and live Jetstream event in seq order, framed per the xrpc.v1.json subprotocol. The kinds, dids, and collections filters are independent predicates ANDed together; each is match-all when omitted. See the parameter and error descriptions for cursor, filtering, and compression semantics.

```json
{
  "type": "subscription",
  "errors": [
    {
      "name": "ConsumerTooSlow",
      "description": "The client is far behind the live tip AND reading below the server's floor rate for a sustained window; the server drops adversarially-slow readers. A merely-slow-but-progressing reader is never dropped."
    },
    {
      "name": "CursorTooOld",
      "description": "Rejected pre-upgrade with HTTP 400, never as a stream error frame: the requested seq cursor is below the server's retention floor. The message carries the floor seq; archive-backfilling clients re-enter backfill from their last durable seq."
    },
    {
      "name": "UnknownZstdDictionary",
      "description": "Rejected pre-upgrade with HTTP 400, never as a stream error frame: the zstdDictionary ID is unknown or retired. The message carries the current dictionary ID; re-fetch via network.bsky.jetstream.getZstdDictionary."
    }
  ],
  "message": {
    "schema": {
      "refs": [
        "#commit",
        "#identity",
        "#account",
        "#sync",
        "#info"
      ],
      "type": "union"
    }
  },
  "parameters": {
    "type": "params",
    "properties": {
      "dids": {
        "type": "array",
        "items": {
          "type": "string",
          "format": "did"
        },
        "maxLength": 10000,
        "description": "Repo DIDs to receive events for; applies to every event kind. Omitted or empty: all repos."
      },
      "kinds": {
        "type": "array",
        "items": {
          "enum": [
            "commit",
            "identity",
            "account",
            "sync"
          ],
          "type": "string"
        },
        "maxLength": 4,
        "description": "Event kinds to receive; values are the message $type fragment names. Omitted or empty: all kinds. A value outside the enum is rejected pre-upgrade with HTTP 400 (InvalidRequest) rather than silently never matching."
      },
      "cursor": {
        "type": "integer",
        "description": "Resume position, inclusive: the server replays events with seq >= cursor and the client dedups the overlap. Values >= 1e15 are interpreted as a unix-microseconds timestamp instead of a seq and translated to the first seq witnessed at or after that instant; a timestamp below the retention floor clamps up to the floor and an #info OutdatedCursor frame is sent. Omitted: start at the live tip."
      },
      "collections": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "maxLength": 100,
        "description": "Collection NSIDs or '<prefix>.*' patterns; constrains which commit events are delivered. Non-commit kinds are unaffected — combine with kinds=commit for a commits-only collection stream. Rejected pre-upgrade with HTTP 400 (InvalidRequest) when kinds is set and excludes commit, since the filter could never apply. Omitted or empty: all collections."
      },
      "zstdDictionary": {
        "type": "integer",
        "minimum": 1,
        "description": "Jetstream extension: opt into dict-zstd frame compression with the given zstd dictionary ID (obtained via network.bsky.jetstream.getZstdDictionary). Frames then arrive as binary websocket messages, each one zstd frame whose decompressed bytes are exactly the xrpc.v1.json text frame. An unknown or retired ID is rejected pre-upgrade with HTTP 400 carrying the current ID."
      },
      "maxMessageSizeBytes": {
        "type": "integer",
        "default": 0,
        "maximum": 4294967295,
        "minimum": 0,
        "description": "Skip events whose uncompressed frame (envelope included) exceeds this many bytes. 0 (default) means no limit."
      }
    }
  },
  "description": "Stream every archived and live Jetstream event in seq order, framed per the xrpc.v1.json subprotocol. The kinds, dids, and collections filters are independent predicates ANDed together; each is match-all when omitted. See the parameter and error descriptions for cursor, filtering, and compression semantics.",
  "subprotocol": "xrpc.v1.json"
}
```

### `network.bsky.jetstream.subscribeEvents#sync`

**Type**: `object`

An archived #sync event (broken commit chain; consumers should resync the repo), wrapping the upstream firehose event verbatim. Never emitted on the legacy v1 /subscribe wire.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `did` | `string` (did) | Yes |  |
| `seq` | `integer` | Yes |  |
| `sync` | `ref` → `com.atproto.sync.subscribeRepos#sync` | Yes | The upstream event; its seq and time are the upstream relay's, not Jetstream's. |
| `time` | `string` (datetime) | Yes | The time Jetstream witnessed this event, microsecond precision. Timestamp imports apply only to record (commit) events, so this is always the witnessed time. |

### `network.bsky.jetstream.subscribeEvents#commit`

**Type**: `object`

A single record mutation (create, update, or delete).

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `cid` | `string` (cid) | No | CID of the record. Absent for deletes. |
| `did` | `string` (did) | Yes |  |
| `rev` | `string` (tid) | Yes | The repo rev of the commit that produced this op. |
| `seq` | `integer` | Yes | Jetstream's monotonic per-event sequence number; the stream cursor. |
| `rkey` | `string` (record-key) | Yes | Record key. |
| `time` | `string` (datetime) | Yes | The event's display timestamp, microsecond precision: when Jetstream witnessed the event, unless an operator timestamp import overrode it. Timestamp cursors translate against the witnessed time, so after an import this value may not be a faithful resume position. |
| `record` | `unknown` | No | The record decoded to JSON. Absent for deletes. |
| `operation` | `string` | Yes |  |
| `collection` | `string` (nsid) | Yes | Collection NSID of the record. |

### `network.bsky.jetstream.subscribeEvents#account`

**Type**: `object`

An account status change (active/deactivated/deleted/...), wrapping the upstream firehose event verbatim.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `did` | `string` (did) | Yes |  |
| `seq` | `integer` | Yes |  |
| `time` | `string` (datetime) | Yes | The time Jetstream witnessed this event, microsecond precision. Timestamp imports apply only to record (commit) events, so this is always the witnessed time. |
| `account` | `ref` → `com.atproto.sync.subscribeRepos#account` | Yes | The upstream event; its seq and time are the upstream relay's, not Jetstream's. |

### `network.bsky.jetstream.subscribeEvents#identity`

**Type**: `object`

An identity change (handle or DID document update), wrapping the upstream firehose event verbatim.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `did` | `string` (did) | Yes |  |
| `seq` | `integer` | Yes |  |
| `time` | `string` (datetime) | Yes | The time Jetstream witnessed this event, microsecond precision. Timestamp imports apply only to record (commit) events, so this is always the witnessed time. |
| `identity` | `ref` → `com.atproto.sync.subscribeRepos#identity` | Yes | The upstream event; its seq and time are the upstream relay's, not Jetstream's. |

## Raw Schema

```json
{
  "id": "network.bsky.jetstream.subscribeEvents",
  "defs": {
    "info": {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "knownValues": [
            "OutdatedCursor"
          ]
        },
        "message": {
          "type": "string"
        }
      },
      "description": "An advisory, non-fatal notice about the stream (mirrors com.atproto.sync.subscribeRepos#info). Carries no seq and does not advance the cursor. OutdatedCursor is sent as the first frame when a unix-microseconds timestamp cursor below the retention floor was clamped up to the floor; the message names the seq actually resumed from."
    },
    "main": {
      "type": "subscription",
      "errors": [
        {
          "name": "ConsumerTooSlow",
          "description": "The client is far behind the live tip AND reading below the server's floor rate for a sustained window; the server drops adversarially-slow readers. A merely-slow-but-progressing reader is never dropped."
        },
        {
          "name": "CursorTooOld",
          "description": "Rejected pre-upgrade with HTTP 400, never as a stream error frame: the requested seq cursor is below the server's retention floor. The message carries the floor seq; archive-backfilling clients re-enter backfill from their last durable seq."
        },
        {
          "name": "UnknownZstdDictionary",
          "description": "Rejected pre-upgrade with HTTP 400, never as a stream error frame: the zstdDictionary ID is unknown or retired. The message carries the current dictionary ID; re-fetch via network.bsky.jetstream.getZstdDictionary."
        }
      ],
      "message": {
        "schema": {
          "refs": [
            "#commit",
            "#identity",
            "#account",
            "#sync",
            "#info"
          ],
          "type": "union"
        }
      },
      "parameters": {
        "type": "params",
        "properties": {
          "dids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "did"
            },
            "maxLength": 10000,
            "description": "Repo DIDs to receive events for; applies to every event kind. Omitted or empty: all repos."
          },
          "kinds": {
            "type": "array",
            "items": {
              "enum": [
                "commit",
                "identity",
                "account",
                "sync"
              ],
              "type": "string"
            },
            "maxLength": 4,
            "description": "Event kinds to receive; values are the message $type fragment names. Omitted or empty: all kinds. A value outside the enum is rejected pre-upgrade with HTTP 400 (InvalidRequest) rather than silently never matching."
          },
          "cursor": {
            "type": "integer",
            "description": "Resume position, inclusive: the server replays events with seq >= cursor and the client dedups the overlap. Values >= 1e15 are interpreted as a unix-microseconds timestamp instead of a seq and translated to the first seq witnessed at or after that instant; a timestamp below the retention floor clamps up to the floor and an #info OutdatedCursor frame is sent. Omitted: start at the live tip."
          },
          "collections": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxLength": 100,
            "description": "Collection NSIDs or '<prefix>.*' patterns; constrains which commit events are delivered. Non-commit kinds are unaffected — combine with kinds=commit for a commits-only collection stream. Rejected pre-upgrade with HTTP 400 (InvalidRequest) when kinds is set and excludes commit, since the filter could never apply. Omitted or empty: all collections."
          },
          "zstdDictionary": {
            "type": "integer",
            "minimum": 1,
            "description": "Jetstream extension: opt into dict-zstd frame compression with the given zstd dictionary ID (obtained via network.bsky.jetstream.getZstdDictionary). Frames then arrive as binary websocket messages, each one zstd frame whose decompressed bytes are exactly the xrpc.v1.json text frame. An unknown or retired ID is rejected pre-upgrade with HTTP 400 carrying the current ID."
          },
          "maxMessageSizeBytes": {
            "type": "integer",
            "default": 0,
            "maximum": 4294967295,
            "minimum": 0,
            "description": "Skip events whose uncompressed frame (envelope included) exceeds this many bytes. 0 (default) means no limit."
          }
        }
      },
      "description": "Stream every archived and live Jetstream event in seq order, framed per the xrpc.v1.json subprotocol. The kinds, dids, and collections filters are independent predicates ANDed together; each is match-all when omitted. See the parameter and error descriptions for cursor, filtering, and compression semantics.",
      "subprotocol": "xrpc.v1.json"
    },
    "sync": {
      "type": "object",
      "required": [
        "seq",
        "did",
        "time",
        "sync"
      ],
      "properties": {
        "did": {
          "type": "string",
          "format": "did"
        },
        "seq": {
          "type": "integer"
        },
        "sync": {
          "ref": "com.atproto.sync.subscribeRepos#sync",
          "type": "ref",
          "description": "The upstream event; its seq and time are the upstream relay's, not Jetstream's."
        },
        "time": {
          "type": "string",
          "format": "datetime",
          "description": "The time Jetstream witnessed this event, microsecond precision. Timestamp imports apply only to record (commit) events, so this is always the witnessed time."
        }
      },
      "description": "An archived #sync event (broken commit chain; consumers should resync the repo), wrapping the upstream firehose event verbatim. Never emitted on the legacy v1 /subscribe wire."
    },
    "commit": {
      "type": "object",
      "required": [
        "seq",
        "did",
        "time",
        "rev",
        "operation",
        "collection",
        "rkey"
      ],
      "properties": {
        "cid": {
          "type": "string",
          "format": "cid",
          "description": "CID of the record. Absent for deletes."
        },
        "did": {
          "type": "string",
          "format": "did"
        },
        "rev": {
          "type": "string",
          "format": "tid",
          "description": "The repo rev of the commit that produced this op."
        },
        "seq": {
          "type": "integer",
          "description": "Jetstream's monotonic per-event sequence number; the stream cursor."
        },
        "rkey": {
          "type": "string",
          "format": "record-key",
          "description": "Record key."
        },
        "time": {
          "type": "string",
          "format": "datetime",
          "description": "The event's display timestamp, microsecond precision: when Jetstream witnessed the event, unless an operator timestamp import overrode it. Timestamp cursors translate against the witnessed time, so after an import this value may not be a faithful resume position."
        },
        "record": {
          "type": "unknown",
          "description": "The record decoded to JSON. Absent for deletes."
        },
        "operation": {
          "type": "string",
          "knownValues": [
            "create",
            "update",
            "delete"
          ]
        },
        "collection": {
          "type": "string",
          "format": "nsid",
          "description": "Collection NSID of the record."
        }
      },
      "description": "A single record mutation (create, update, or delete)."
    },
    "account": {
      "type": "object",
      "required": [
        "seq",
        "did",
        "time",
        "account"
      ],
      "properties": {
        "did": {
          "type": "string",
          "format": "did"
        },
        "seq": {
          "type": "integer"
        },
        "time": {
          "type": "string",
          "format": "datetime",
          "description": "The time Jetstream witnessed this event, microsecond precision. Timestamp imports apply only to record (commit) events, so this is always the witnessed time."
        },
        "account": {
          "ref": "com.atproto.sync.subscribeRepos#account",
          "type": "ref",
          "description": "The upstream event; its seq and time are the upstream relay's, not Jetstream's."
        }
      },
      "description": "An account status change (active/deactivated/deleted/...), wrapping the upstream firehose event verbatim."
    },
    "identity": {
      "type": "object",
      "required": [
        "seq",
        "did",
        "time",
        "identity"
      ],
      "properties": {
        "did": {
          "type": "string",
          "format": "did"
        },
        "seq": {
          "type": "integer"
        },
        "time": {
          "type": "string",
          "format": "datetime",
          "description": "The time Jetstream witnessed this event, microsecond precision. Timestamp imports apply only to record (commit) events, so this is always the witnessed time."
        },
        "identity": {
          "ref": "com.atproto.sync.subscribeRepos#identity",
          "type": "ref",
          "description": "The upstream event; its seq and time are the upstream relay's, not Jetstream's."
        }
      },
      "description": "An identity change (handle or DID document update), wrapping the upstream firehose event verbatim."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1
}
```
