···6677Asterism, meanwhile, consumes cryptographically verifiable events directly from the Firehose, and filters them by the collection of your choice. There's no Jetstream in the middle, meaning fewer moving parts. And while Asterism has significant bandwidth requirements, the filtered index is significantly smaller and scales with your application, not with the network.
8899-> **Early stage.** Functional but *very* incomplete. APIs may change, backfill is rudimentary, and several features are not yet implemented. See [Roadmap](#roadmap).
99+> **Early stage.** Functional but _very_ incomplete. APIs may change, backfill is rudimentary, and several features are not yet implemented. See [Roadmap](#roadmap).
10101111## What it does
1212···51515252Every flag can also be set with an environment variable.
53535454-| Flag | Environment variable | Default | Description |
5555-|---|---|---|---|
5656-| `--collections` | `ASTERISM_COLLECTIONS` | empty | Comma-separated collection NSIDs to index. Empty means all collections. |
5757-| `--backfill` | `ASTERISM_BACKFILL` | false | Backfill existing repos for configured collections on startup. |
5858-| `--database` | `ASTERISM_DATABASE` | `asterism.db` | SQLite database path. |
5959-| `--listen` | `ASTERISM_LISTEN` | `:8081` | HTTP API listen address. |
6060-| `--relay` | `ASTERISM_RELAY` | `relay1.us-east.bsky.network` | Relay host. Asterism derives the Firehose websocket and relay HTTP API URLs from this host. |
5454+| Flag | Environment variable | Default | Description |
5555+| --------------- | ---------------------- | ----------------------------- | ------------------------------------------------------------------------------------------- |
5656+| `--collections` | `ASTERISM_COLLECTIONS` | empty | Comma-separated collection NSIDs to index. Empty means all collections. |
5757+| `--backfill` | `ASTERISM_BACKFILL` | false | Backfill existing repos for configured collections on startup. |
5858+| `--database` | `ASTERISM_DATABASE` | `asterism.db` | SQLite database path. |
5959+| `--listen` | `ASTERISM_LISTEN` | `:8081` | HTTP API listen address. |
6060+| `--relay` | `ASTERISM_RELAY` | `relay1.us-east.bsky.network` | Relay host. Asterism derives the Firehose websocket and relay HTTP API URLs from this host. |
61616262For example:
6363···89899090List distinct DIDs that have records linking to a subject. Paginated.
91919292-| Parameter | Description |
9393-|---|---|
9494-| `subject` | Target AT-URI, DID, or URL (required) |
9595-| `source` | Collection and field path, e.g. `app.bsky.feed.like:subject.uri` (required) |
9696-| `limit` | Page size, 1–1000 (default 100) |
9797-| `cursor` | Pagination cursor from previous response |
9292+| Parameter | Description |
9393+| --------- | --------------------------------------------------------------------------- |
9494+| `subject` | Target AT-URI, DID, or URL (required) |
9595+| `source` | Collection and field path, e.g. `app.bsky.feed.like:subject.uri` (required) |
9696+| `limit` | Page size, 1–1000 (default 100) |
9797+| `cursor` | Pagination cursor from previous response |
98989999Response: `{"total": 42, "linking_dids": ["did:plc:..."], "cursor": "..."}`
100100···102102103103List source records linking to a subject. Paginated.
104104105105-| Parameter | Description |
106106-|---|---|
107107-| `subject` | Target AT-URI, DID, or URL (required) |
108108-| `source` | Collection and field path (required) |
109109-| `did` | Filter to specific actor DIDs (repeatable) |
110110-| `limit` | Page size, 1–1000 (default 100) |
105105+| Parameter | Description |
106106+| --------- | ----------------------------------------------- |
107107+| `subject` | Target AT-URI, DID, or URL (required) |
108108+| `source` | Collection and field path (required) |
109109+| `did` | Filter to specific actor DIDs (repeatable) |
110110+| `limit` | Page size, 1–1000 (default 100) |
111111| `reverse` | Return links in ascending order (default false) |
112112-| `cursor` | Pagination cursor from previous response |
112112+| `cursor` | Pagination cursor from previous response |
113113114114Response: `{"total": 42, "records": [{"did": "...", "collection": "...", "rkey": "..."}], "cursor": "..."}`
115115···119119120120Join records linking to a subject with a second field path on those same records — a one-hop join in a single query. For example, `app.bsky.graph.listitem` records have both a `list` field and a `subject` field; joining them resolves list membership directly instead of requiring a `getBacklinks` call followed by N individual record lookups.
121121122122-| Parameter | Description |
123123-|---|---|
124124-| `subject` | Target AT-URI, DID, or URL (required) |
125125-| `source` | Collection and field path (required) |
126126-| `pathToOther` | Second field path on the same source record (required) |
127127-| `linkDid` | Filter to specific linking-record DIDs (repeatable) |
122122+| Parameter | Description |
123123+| -------------- | ------------------------------------------------------ |
124124+| `subject` | Target AT-URI, DID, or URL (required) |
125125+| `source` | Collection and field path (required) |
126126+| `pathToOther` | Second field path on the same source record (required) |
127127+| `linkDid` | Filter to specific linking-record DIDs (repeatable) |
128128| `otherSubject` | Filter to specific secondary link targets (repeatable) |
129129-| `limit` | Page size, 1–1000 (default 100) |
130130-| `cursor` | Pagination cursor from previous response |
129129+| `limit` | Page size, 1–1000 (default 100) |
130130+| `cursor` | Pagination cursor from previous response |
131131132132Response: `{"total": 42, "items": [{"linkRecord": {"did": "...", "collection": "...", "rkey": "..."}, "otherSubject": "..."}], "cursor": "..."}`
133133···135135136136Like `getManyToMany`, but grouped: counts of linking records per distinct secondary target instead of the individual records themselves. Useful when you only need aggregate counts, e.g. "how many people on each of these lists also follow me" without paginating every membership record.
137137138138-| Parameter | Description |
139139-|---|---|
140140-| `subject` | Target AT-URI, DID, or URL (required) |
141141-| `source` | Collection and field path (required) |
142142-| `pathToOther` | Second field path on the same source record (required) |
143143-| `did` | Filter to specific linking-record DIDs (repeatable) |
138138+| Parameter | Description |
139139+| -------------- | ------------------------------------------------------ |
140140+| `subject` | Target AT-URI, DID, or URL (required) |
141141+| `source` | Collection and field path (required) |
142142+| `pathToOther` | Second field path on the same source record (required) |
143143+| `did` | Filter to specific linking-record DIDs (repeatable) |
144144| `otherSubject` | Filter to specific secondary link targets (repeatable) |
145145-| `limit` | Page size, 1–1000 (default 100) |
146146-| `cursor` | Pagination cursor from previous response |
145145+| `limit` | Page size, 1–1000 (default 100) |
146146+| `cursor` | Pagination cursor from previous response |
147147148148Response: `{"counts_by_other_subject": [{"subject": "...", "total": 42, "distinct": 12}], "cursor": "..."}`
149149···155155156156- [x] Full Constellation API parity (`getBacklinksCount`, `getBacklinkDids`, `getBacklinks`, `getManyToMany`, `getManyToManyCounts`)
157157- [x] Configurable listen address, database path, relay host, and startup backfill
158158-- [ ] Account deletion and deactivation handling
158158+- [x] Account deletion handling
159159+- [ ] Account deactivation handling
159160- [x] Graceful shutdown and Firehose reconnect
160161161162**Medium term**