Where It’s at:// October 2, 2025 By Dan Abramov --- Introduction to the AT Protocol and at:// URIs The AT protocol defines a decentralized system where servers speaking the protocol form the atmosphere, a web of hyperlinked JSON data. Each piece of JSON data is uniquely addressable with an at:// URI, e.g., at://ruuuuu.de/app.bsky.feed.post/3lzy2ji4nms2z at://danabra.mov/sh.tangled.feed.star/3m23ddgjpgn22 at://tessa.germnetwork.com/pub.leaflet.publication/3lzz6juivnc2d Unlike traditional HTTP URIs where authority denotes the hosting domain, in the at:// scheme, the user (the data creator) is the authority. The host serving the data may change without invalidating the URI. --- Resolving an at:// URI: Step-by-Step Process To resolve an at:// URI to the corresponding JSON involves three main steps: Resolve the user handle to an immutable identity (DID). Resolve that DID to the current hosting server. Request the JSON record from the hosting server. --- From Handles to Identities (DID Resolution) Handles are human-readable strings like ruuuuu.de, danabra.mov, but they can change. Digital Identity (DID) is a permanent, immutable identifier for users. Two methods to resolve a handle to a DID: DNS TXT lookup of atproto.<handle> for did=... record. HTTPS GET request to https://<handle>/.well-known/atproto-did. Examples: DNS lookup for atproto.ruuuuu.de returns did:web:iam.ruuuuu.de. DNS lookup for atproto.danabra.mov returns did:plc:fpruhuo22xkm5o7ttr2ktxdo. If DNS TXT record is absent (like for subdomain barackobama.bsky.social), HTTPS lookup works, returning e.g. did:plc:5c6cw3veuqruljoy5ahzerfx. --- From Identities (DIDs) to Hosting Two DID methods supported: did:web DID looks like did:web:iam.ruuuuu.de Fetch DID Document by an HTTPS GET to https://iam.ruuuuu.de/.well-known/did.json. The DID Document contains: alsoKnownAs: confirms the associated handle, e.g. at://ruuuuu.de. verificationMethod: public keys for signature verification. service: includes serviceEndpoint URL where actual data hosting occurs (e.g., https://blacksky.app). Downside: if control of domain iam.ruuuuu.de is lost, the DID Document and thus identity are compromised. did:plc DID looks like did:plc:fpruhuo22xkm5o7ttr2ktxdo (default for Bluesky). Fetch DID Document by querying https://plc.directory/<did>. Contains similar information as did:web: handle association, verification keys, hosting endpoint (e.g., https://morel.us-east.host.bsky.network). Benefits: Not tied to any web domain; identity persists despite domain expiry. Limitations: PLC registry operator has some control and can deny updates or data serving, but all changes are cryptographically chained and queryable for transparency. Bluesky is working on making PLC independent to minimize risks. --- From Hosting to JSON With the serviceEndpoint URL and full DID, you can fetch any JSON record via the getRecord API endpoint. For example, to get the record for at://ruuuuu.de/app.bsky.feed.post/3lzy2ji4nms2z: This returns the pure JSON data, e.g. a social media post with fields like text, langs, createdAt. The JSON is not UI or webpage but structured data following a specific format ($type field). --- AT Permalinks and Canonical URIs Handles are human-friendly but can break links if changed. DIDs are stable and permanent, so at:// URIs with DIDs act as permalinks**. Applications should store and use canonical at:// links with DIDs to avoid link breakage. Example: Fragile: at://ruuuuu.de/app.bsky.feed.post/3lzy2ji4nms2z Stable: