icon picker
Username formats 101

Let me explain about different username formats use in the wild in my own terms.
Last edited 153 days ago by Andrei Jiroh Halili (ajhalili2006)

This document is a living document, if not a work in progress.

If you’re signed into Coda, to switch to the non-published version of this doc and comment on (and ). Please do not spam the doc if you do.
Hello there! Have you ever curious about the different username formats I use in day-to-day communications, especially online and in IRL written communications?

Your typical @username

In a centralized service (coughs in Substack), 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 (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
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 if you need to. High Availability in Kubernetes-like setup for AP-based server implementations is pain.

The fediverse: @username@your.activitypub-instance.tld

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 So if you are at your.activitypub-instance.tld and your username is username, then the fediverse address is username@your.activitypub-instance.tld 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 () with the acct: URI () on the backend, and even some require proper WebFinger support because of heavy reliance on mentions for addressing other profiles. Per , 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:username@your.activitypub-instance.tld 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 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? HTTP/1.1 Host: User-Agent: HTTPie
HTTP/1.1 200 OK Cache-Control: max-age=259200, public Connection: close Content-Security-Policy: base-uri 'none'; default-src 'none'; frame-ancestors 'none'; script-src 'self' 'wasm-unsafe-eval'; font-src 'self'; img-src 'self' data: blob:; style-src 'self' 'nonce-m2QrnxdrWZTLUjIl1gFk9Q=='; media-src 'self' data:; frame-src 'self' https:; child-src 'self' blob:; worker-src 'self' blob:; connect-src 'self' blob: data: wss://; manifest-src 'self'; form-action 'self' Content-Type: application/jrd+json; charset=utf-8 Date: Sat, 24 Dec 2022 14:31:18 GMT Etag: W/"bfe153df7d226f963fe67802f052e0dd" Permissions-Policy: interest-cohort=() Referrer-Policy: same-origin Server: Mastodon Strict-Transport-Security: max-age=63072000; includeSubDomains Transfer-Encoding: chunked Vary: Origin X-Cached: MISS X-Clacks-Overhead: GNU Natalie Nguyen X-Content-Type-Options: nosniff X-Frame-Options: DENY X-Request-Id: 53f439bd-1901-49c7-b51d-33c4461e2b0a X-Runtime: 0.005386 X-Xss-Protection: 0{"subject":"","aliases":["",""],"links":[{"rel":"","type":"text/html","href":""},{"rel":"self","type":"application/activity+json","href":""},{"rel":"","template":"{uri}"}]}
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:
{ "subject": "", "aliases": [ "", "" ], "links": [ { "rel": "", "type": "text/html", "href": "" }, { "rel": "self", "type":"application/activity+json", "href":"" }, { "rel" :"", "template":"{uri}" } ]}
We’ll explain each of them per the WebFinger specification, but most of the client-side and server-side implementations will often need links[1] (to fetch user information in a machine-readable format and not mess around with regex-based HTML web scrapping bullshit) and links[2] (Mostly left for legacy reasons, and the is, as of time of writing, owned by someone else, and it’s a casinio hellscape, and some implementations like TBD don’t support for authorizing remote interactions due to lack of built-in web client).
First of all, the subject key a URI that identifies the entity that the JRD () 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?

Is it Matrix or Element?
* Matrix is the protocol, developed by the UK-registered non-profit . It can also refer to the entire Matrix federation that contains all the users and rooms.
* Element (previously known as is the flagship app of Matrix, developed by the UK-registered for-profit . It can also refer to commercial services that the company offers, such as .
, Element is just one of the apps that accesses Matrix. It is therefore correct to refer to the platform as just “Matrix.” Though, nobody is stopping you from calling it .
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 for additional migraines.
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

TODO (first-time contributors to my docs projects welcome): Explain the history of the tildeverse here through the lens of
Reading both the ActivityPub and Matrix specs could cause migraines to anyone involved, so you might decide to run your own tilde alongside a self-hosted sourcehut instance with Stripe integration for funding server maintenance (assuming your country is supported for setting up standard accounts or gone through setting up a US LLC legal entity via ).

Placeholders used in this doc

your.activitypub-instance.tld or your.homeserver.tld -
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
) instead.