export const metadata = { title: 'Federation Example', description: 'A description of how a typical federation flow might look like', } # Example This page describes a typical federation flow between two servers, `a.social` and `b.social`, in several different contexts. {{ className: 'lead' }} All examples, domains, names and timestamps are **fictional** and are used **for illustrative purposes only**. Some details have been slightly simplified for clarity. ## Sending a Note `@alice` on `a.social` creates a note with the following content: ```markdown Hello, @joe@b.social! How are you doing today? ``` `@alice` has mentioned `@joe@b.social` in the note. ### Resolving the Mention `a.social` resolves the mention by querying `b.social` for the user `joe` using WebFinger. ```bash {{ title: "cURL example" }} curl https://b.social/.well-known/webfinger?resource=acct:joe@b.social -H "Accept: application/json" ``` `b.social` responds with the following JSON: ```json { "subject": "acct:joe@b.social", "links": [ { // [!code focus:5] "rel": "self", "type": "application/vnd.versia+json", "href": "https://b.social/.versia/entities/User/joe" } ] } ``` In a real Versia implementation, usernames would **not** be included in user profile's URL, as they can be changed. Instead, the `id` could be used. This is done for simplicity in this example. ### Fetching the User `a.social` fetches the user profile of `joe` from `b.social` using the URL provided in the WebFinger response. ```bash curl https://b.social/.versia/entities/User/joe \ -H "Accept: application/vnd.versia+json" \ -H "User-Agent: CoolServer/1.0 (https://coolserver.com)" \ # The request is signed by a.social's instance private key -H "Versia-Signature: /CjB2L9bcvRg+uP19B4/rqy7Ji9/cqMFPlL3GVCIndnQjYyOpBzJEAl9weDnXm7Jrqa3y6sBC+EYWKThO2r9Bw==" \ -H "Versia-Signed-By: a.social" \ -H "Versia-Signed-At: 1729241687" ``` `b.social` responds with the following JSON: ```json { "id": "bde22zi3ca8762", // [!code focus:10] "type": "User", "created_at": "2024-10-13T18:48:19Z", "avatar": { "image/webp": { "content": "https://cdn.b.social/avatars/joe.webp", "remote": true } }, // [!code focus:3] "display_name": "Joe Swanson (Winter Arc :gigachad:)", "username": "joe", "extensions": { "pub.versia:custom_emojis": { "emojis": [ { "name": ":gigachad:", "content": { "image/png": { "content": "https://cdn.b.social/emojis/gigachad.png", "remote": true } } } ] } }, } ``` `a.social` now has the user profile of `joe` and can display the note with the correct user information. ### Serializing the Note Finally, `a.social` serializes the note to send it to `joe`. ```json { "id": "782addd9-c051-4eea-8ba4-23d561d0c5bb", // [!code focus:6] "type": "Note", "created_at": "2024-12-01T12:19:06Z", "author": "alice", "category": "microblog", // [!code focus:11] "content": { "text/html": { "content": "Hello, @joe@b.social! How are you doing today?", "remote": false, }, "text/plain": { "content": "Hello, @joe@b.social! How are you doing today?", "remote": false, } }, "group": "public", "mentions": [ // [!code focus:3] "b.social:bde22zi3ca8762" ] } ``` It is now time for `a.social` to send the note to `joe`. ### Sending the Note `a.social` sends the note to `joe`'s inbox at `b.social`. ```bash curl -X POST https://b.social/.versia/v0.6/inbox \ -H "Content-Type: application/vnd.versia+json; charset=utf-8" \ -H "Accept: application/json" \ -H "User-Agent: CoolerServer/1.0 (https://coolerserver.com)" \ # The request is signed by Alice's private key -H "Versia-Signature: 9BrfplAPVH6OEqlV5eX7MazaZAInSCPODZcBEvMliBi/OwfbCAsezlb0O9jUX9ZcbBA68ThA4WUgS9V+42rfAQ==" \ -H "Versia-Signed-By: a.social" \ -H "Versia-Signed-At: 1733051946" ``` `b.social` responds with a `202 Accepted` status code. ### Displaying the Note The software on `b.social` processes the note and shows it to `joe` using whatever interface it has. `joe` can now see the note from `@alice` on `a.social` and respond to it.