Skip to main content

the addressing problem

to read or write a record, pdsx needs to know:
  1. which repository contains it
  2. which collection within that repository
  3. which specific record (if applicable)
ATProto solves this with AT-URIs and DIDs.

AT-URI format

AT-URIs identify records using this structure:
example:
components:
  • scheme: always at://
  • authority: DID or handle identifying the repository
  • collection: NSID of the collection (optional)
  • rkey: record key within collection (optional)

authority: DID vs handle

using DIDs

DIDs are:
  • permanent: never change
  • decentralized: not controlled by any provider
  • portable: work even if user changes PDS
  • cryptographic: tied to signing keys
best for: durable references, long-term storage

using handles

handles are:
  • human-readable: easier to type/remember
  • changeable: user can update their handle
  • reassignable: if abandoned, someone else can claim it
  • DNS/HTTP-based: resolved via DNS or .well-known
best for: user-facing displays, temporary references critical limitation: if user changes handle, handle-based URIs break or point to wrong repository.

how pdsx resolves addresses

with -r flag (handle)

resolution flow:
  1. resolve handle → DID
    • try DNS: _atproto.zzstoatzz.io TXT record
    • fallback to HTTPS: https://zzstoatzz.io/.well-known/atproto-did
  2. resolve DID → PDS URL
    • fetch DID document
    • extract PDS endpoint
  3. query PDS for records
  4. return results

with -r flag (DID)

resolution flow:
  1. skip handle resolution (already have DID)
  2. resolve DID → PDS URL
  3. query PDS
  4. return results

without -r flag (authenticated)

uses authenticated session:
  1. already authenticated with PDS
  2. session knows your DID
  3. query your own repository
  4. return results

shorthand URIs in pdsx

IMPORTANT: Shorthand URIs (collection/rkey) only work when you have an active authenticated session. Without authentication, you must use full AT-URIs (at://authority/collection/rkey). If you see an “invalid URI format” error, this is likely why.
when authenticated, pdsx supports shorthand:

full URI

shorthand (when authenticated)

pdsx automatically:
  • uses your DID from session
  • constructs full URI
  • executes operation
this only works for your own repository - you’re authenticated to it.

did document structure

dids resolve to did documents that contain:
key fields pdsx uses:
  • service: which pds hosts this repository
  • alsoKnownAs: current handle (for verification)
  • verificationMethod: public keys (for cryptographic verification)

pds discovery

pdsx finds the pds hosting a repository:
  1. resolve authority (handle or did) → did
  2. fetch did document from plc directory
  3. extract service entry with type AtprotoPersonalDataServer
  4. use serviceEndpoint as pds url
example:

—pds flag

pdsx lets you override pds discovery:
useful for:
  • testing local pds
  • using non-standard pds
  • debugging
note: authentication must still be with that specific pds.

why this addressing model matters

portability

if user migrates pds:
  1. update did document → new service endpoint
  2. did-based uris still work
  3. handle-based uris still work (if handle unchanged)
  4. pdsx follows did document to find new pds

federation

different users on different pds instances:

handles as aliases

handles are just friendly names:
  • did is permanent identity
  • handle can change
  • handle can be reassigned
  • did document links them

authentication and addressing

reading public records

no auth needed:
  • pdsx resolves handle → did → pds
  • queries pds as anonymous client
  • pds returns public records

writing to own repository

auth flow:
  1. pdsx creates session with pds (using credentials)
  2. pds validates credentials
  3. pds returns session token + your did
  4. pdsx uses session for subsequent requests
  5. pds ensures you’re writing to your own repository

cross-repository references

when creating a record that references another repository’s record:
pdsx:
  • doesn’t need auth to other-user’s repository
  • just includes their uri in your record
  • stores in your repository
  • reference points across repositories

uri validation

pdsx performs minimal uri validation: valid formats:
invalid formats:

why understanding addressing matters for pdsx

-r flag specifies repository: can be handle or did
shorthand requires auth: only works for your own repository
full uris are more durable: use dids, not handles
pds is discovered automatically: unless overridden with —pds

from concept to command

these addressing concepts translate directly to pdsx usage: reading with handle:
pdsx resolves handle → DID → PDS → fetches records reading with DID (more durable):
pdsx finds PDS from DID document → fetches records shorthand (authenticated only):
pdsx uses client.me.did from session to construct full URI

further reading