to switch to the non-published version of this doc and comment on (and even suggest edits). Please do not spam the doc if you do.
Hello there! Have you ever curious about the different username formats I use
Your typical @username
In a centralized service, you are @username on that particular service (and it can be different on other centralized service) and if you want to bring in your friends and followers into that app, you would say hey i’m @username on service.xyz (Discord is chaotic in this case, username#1234, but you don’t want anyone to spam your inbox and friend requests, so you setup a server with Server Boost 3 for custom invite URL, so this should be discord.gg/username.)
For users who are on different forums and maybe IRC networks behind load balancing stuff, apologies for the confusion caused by this. You might also consider
The fediverse: @email@example.com
Fediverse user addresses look like email addresses, when in fact it’s not.
When you write it, browsers and even Coda think it’s a email address (and when some uninitiated person) attempts to send email to that, they’ll be greeted by the email service’s MTA servers that the email address on that homeserver (or instance, if you don’t like mixing ActivityPub and Matrix protocols together) doesn’t exist.
This is where things get interesting. So if centralized services’ overlords decided to join the fediverse through implementing ActivityPub (or Zot, OStatus or disapora), WebFinger and all the nifty gritty things to federate to other services, we can suffix the app’s root domain in form of @service.xyz. So if you are at your.activitypub-instance.tld and your username is username, then the fediverse address is firstname.lastname@example.org which is kinda confusing for most URL parsers since this is often confused with the regular email addresses, as mentioned in the warning above.
The technical bits (expand this to see them)
Most ActivityPub implementations implement WebFinger (
, its internal logic depends almost completely on acct: URIs or username@domain representations and searching for any objects or profiles from an ActivityPub implementation without WebFinger will fail because the author cannot be converted to a user in the local database.
Third-party clients, especially cross-posting services will often parse the fediverse address first before phoning home the homeserver/instance server-side at https://your.activitypub-instance.tld/.well-known/webfinger, with acct:email@example.com as the value for the resource query parameter via a regular GET request to confirm whenever a instance is still online and that user exists there before redirecting to an OAuth2 (or OIDC) authorization prompt screen.
Okay, enough examples, let’s go to the demo. Suppose you’re looking up for Andrei Jiroh’s Mastodon account on tilde.zone via your client’s search feature and you slapped the full fediverse address (or the profile URL for brevity) to the search field. When you hit Enter, the client does an authenticated GET request to /api/v2/search and as the server receives the data and realises that such user isn’t exist yet on its local database, so it will call the WebFinger endpoint on the remote user’s homeserver.
GET /.well-known/webfinger?resource=acct%3Aajhalili2006%40tilde.zone HTTP/1.1
The JSON response is a bit of a one-liner and we don’t need the full request and response headers here, but we can prettify it with jq (if you ever did this in CLI throught the Httpie CLI or other HTTP client) or just hide the hell out of there. Here’s the single-handedly pretty-formatted JSON response:
We’ll explain each of them per the WebFinger specification, but most of the client-side and server-side implementations will often need links (to fetch user information in a machine-readable format and not mess around with regex-based HTML web scrapping bullshit) and links (Mostly left for legacy reasons, and the ostatus.org is, as of time of writing, owned by someone else, and it’s a casinio hellscape, and some implementations like TBD don’t support
) describes, and its value returned by a WebFinger resource MAY differ from the value of the "resource" parameter used in the client's request due to various reasons, such as changing usernames or even migrating between homeservers. There might be the case where the resource server prefers to express URIs in canonical form.
The [matrix]: @username:your.homeserver.tld (or just @username:homeserver.tld if domain delegated)
Is it the movie series or the network/portocol/spec?
Now that our ActivityPub goes hybrid with the implementation of Matrix protocol for more than end-to-end encryption of chats
Technical bits (expand this to see them)
Now that we understand how ActivityPub implementations do user lookups for remote users, we’ll then read the Matrix protocol spec to understand the Matrix side of user lookups, specifically the User-Server and Server Federation APIs and
the codebase and we found some code relating to how the reference homeserver store and queries user profile for clients, but we need the query part (and not all the database schema migrations, server routing hell, etc)
Tildeverse + sourcehut: ~username and sr.ht/~username
TODO (first-time contributors to my docs projects welcome): Explain the history of the tildeverse here through the lens of