1# tap 2 3bluesky's ATProto sync utility for backfilling and streaming custom lexicons. 4 5## install 6 7```bash 8go install github.com/bluesky-social/indigo/cmd/tap@latest 9``` 10 11binary lands at `~/go/bin/tap` 12 13## run locally 14 15```bash 16TAP_SIGNAL_COLLECTION=fm.plyr.track \ 17TAP_COLLECTION_FILTERS=fm.plyr.* \ 18TAP_LOG_LEVEL=info \ 19~/go/bin/tap run 20``` 21 22this will: 231. enumerate all repos with `fm.plyr.track` via `com.atproto.sync.listReposByCollection` 242. backfill those repos, extracting any `fm.plyr.*` records 253. stream the firehose for new records 264. serve events via websocket at `ws://localhost:2480/channel` 27 28## what we found 29 30initial network scan (dec 2025): 31- 35 repos with `fm.plyr.track` records 32- 497 total records indexed 33 34breakdown: 35``` 36fm.plyr.track 273 37fm.plyr.like 90 38fm.plyr.list 41 39fm.plyr.dev.track 18 40fm.plyr.comment 15 41fm.plyr.actor.profile 13 42(plus staging/dev variants) 43``` 44 45## consuming events 46 47events come through `/channel` websocket as JSON: 48 49```json 50{ 51 "id": 439, 52 "type": "record", 53 "record": { 54 "live": false, 55 "did": "did:plc:...", 56 "collection": "fm.plyr.track", 57 "rkey": "3m7m3wyasmi2l", 58 "action": "create", 59 "record": { 60 "title": "...", 61 "artist": "...", 62 "audioUrl": "https://..." 63 } 64 } 65} 66``` 67 68ack events to consume them: `{"ack": <id>}` 69 70see `sandbox/tap/read_events.py` for example consumer. 71 72## api endpoints 73 74- `GET /health` - status check 75- `POST /repos/add` - track a DID 76- `POST /repos/remove` - stop tracking 77- `GET /stats/repo-count` - tracked repos 78- `GET /stats/record-count` - indexed records 79- `WS /channel` - event stream 80 81## resources 82 83- [tap README](https://github.com/bluesky-social/indigo/blob/main/cmd/tap/README.md) 84- [bailey's guide](https://marvins-guide.leaflet.pub/3m7ttuppfzc23) 85- [@atproto/tap](https://www.npmjs.com/package/@atproto/tap) - typescript client