I wanted to add a record validator for Taproot but couldn't find a good place to look up all the schemas at once.
The ATProto spec defines how lexicons should be published (in com.atproto.lexicon.schema collections) and how the authority should be verified (via _lexicon DNS TXT records). But there wasn't a central place to discover and browse verified schemas.
That's when Eli published their clever embedded PDS concept for stream.place, and it sorta clicked.
What if the PDS repo is the registry?
Introducing Lexicon Store - A lexicon registry on a PDS
I briefly talked about it during the lexicon discussion in ATProto_NYC meetup, but didn't get to complete it till now.
Lex is More
There's already a lexicon scraper from Mary, lexicon.garden from Nick, and even a lexicon repository coming soon from Bluesky team, so this felt like the right time to release it.
Lexicon Store takes an unconventional approach:
the did:web:lexicon.store PDS repo is the lexicon registry. Every verified lexicon lives at
at://did:web:lexicon.store/com.atproto.lexicon.schema/{nsid}
How it works
Users publish lexicon schemas as records in com.atproto.lexicon.schema collection in their repo.
Those records flow through the firehose.
The indexer:
1. Listens for these schema records
2. Verifies authority per the Lexicon Spec
3. Stores verified schemas in the registry PDS
The indexer also writes to several other collections in the repo for general indexer logging, collection-level logging, lexicon version history, authority metadata, etc.
You can browse the registry in PDSls
https://pdsls.dev/at://did:web:lexicon.store/com.atproto.lexicon.schema?reverse=true
(thank you @juli.ee for adding the reverse option in the URL)
Or browse the registry frontend at https://lexicon.store/
The website pulls the verified lexicon schemas from the PDS.
Manual Indexing:
If your schema is missing in the registry, you can request a manual indexing for either a single NSID, or a domain(or subdomain) or for all the lexicons from a user's repo.
You can even watch the schema getting indexed or rejected in real-time, with reasons. Everything is stored on the PDS.
Once indexed, validated lexicons will appear in the registry and can be viewed at:
Registry: lexicon.store/com.atproto.lexicon.schema/{nsid}
PDSLS: pdsls.dev/at://did:web:lexicon.store/com.atproto.lexicon.schema/{nsid}
JSON: atpi.at://did:web:lexicon.store/com.atproto.lexicon.schema/{nsid}
For example, app.bsky.actor.getProfile can be seen here in registry, pdsls and atpi
There is also a separate log for each collection at
at://did:web:lexicon.store/store.lexicon.{nsid}.log
and a published version history (based on the lexicon schema's cid) at
at://did:web:lexicon.store/store.lexicon.{nsid}.versions
For example, here is log and version history for app.bsky.actor.getProfile
(Earlier version of the code was storing it in {nsid}.{metadata}
but after getting feedback from Evan, moved this over back to store.lexicon.{nsid}.{metadata})
For schemas that fail the validation during indexing, they get recorded here
at://did:web:lexicon.store/store.lexicon.unverified
with an explanation on why they failed
Rogue records that come from other users who aren't the authority for that lexicon are rejected.
Still wrapping my head around all the edge cases. If you spot something I missed, please let me know!
Feedback is appreciated.
You can view the entire list of Lexicon Store PDS collections on PDSLS- that's LSPDS on PDSLS ;)
I can finally check this off now.
(Also, if you don't want to procrastinate like me and want to achieve your daily goals in 2026, check out @goals.garden at https://goals.garden/)
Lex Do This.