Example
The signatures are real. They were made with the example key from Signing Requests, so you can check them by exporting its public key.
This page follows one note from a.example to b.example, from resolving a mention to displaying the note. Notes come from the Social extension, which both instances implement.
Sending a Note
The whole exchange looks like this, and the sections below go through each step.
@aliceposts a note that mentions@joe@b.example.- Request:
GET /.well-known/ webfinger? resource= acct:joe@b.example Resolve the mention using WebFinger. - Response:Responds with the URL of
joe’s profile. - Request:
GET /.versia/ v0.7/ instance Verify the signature.b.examplefetchesa.example’s metadata if it does not have its public key yet. - Response:Responds with its
InstanceMetadata, which holds the public key. - Response:Responds with the
Userentity. - Response:
202 AcceptedVerifies the signature with the key it already has, then responds. - Display the note to
joe.
@alice on a.example creates a note with the following content:
Hello, @joe@b.example! How are you doing today?
@alice has mentioned @joe@b.example in the note.
Resolving the Mention
a.example resolves the mention by querying b.example for the user joe using WebFinger.
curl "https://b.example/.well-known/webfinger?resource=acct:joe@b.example" -H "Accept: application/jrd+json"
b.example responds with the following JSON:
{
"subject": "acct:joe@b.example",
"links": [
{
"rel": "self",
"type": "application/vnd.versia+json",
"href": "https://b.example/.versia/v0.7/entities/User/034de9r4fr006"
}
]
}
Fetching the User
a.example fetches the user profile of joe from b.example using the URL provided in the WebFinger response.
# The request is signed by a.example's instance private key
curl https://b.example/.versia/v0.7/entities/User/034de9r4fr006 \
-H "Accept: application/vnd.versia+json" \
-H "User-Agent: CoolServer/1.0 (https://coolserver.example)" \
-H "Versia-Signature: L8icLiUGIu0kznC4Z1DgSMIzAvounZ0fJ7QsJFl+yFxnkb8qRQ/G2IT549f5yGcpfRFJQF87S12dWUM3161jDQ==" \
-H "Versia-Signed-By: a.example" \
-H "Versia-Signed-At: 1733051945"
b.example verifies the signature before it answers. That takes a.example’s public key, so if b.example does not have it yet, it reads it from a.example’s metadata:
curl https://a.example/.versia/v0.7/instance -H "Accept: application/vnd.versia+json"
b.example then responds with the following JSON. Its response is signed too, and a.example verifies it the same way, using b.example’s public key.
{
"id": "034de9r4fr006",
"type": "User",
"created_at": "2024-10-13T18:48:19Z",
"avatar": {
"url": "https://cdn.example.com/avatars/joe.webp",
"media_type": "image/webp"
},
"display_name": "Joe Swanson (Winter Arc :gigachad:)",
"username": "joe",
"manually_approves_subscribers": false,
"indexable": true,
"extensions": {
"pub.versia:custom_emojis": {
"emojis": [
{
"name": ":gigachad:",
"content": {
"url": "https://cdn.example.com/emojis/gigachad.png",
"media_type": "image/png"
}
}
]
}
}
}
a.example now has the user profile of joe and can display the note with the correct user information.
Serializing the Note
Finally, a.example serializes the note to send it to joe.
{
"id": "033r20svqa000",
"type": "pub.versia:social/Note",
"created_at": "2024-12-01T11:19:04Z",
"attachments": [],
"author": "a.example:034d45r3e6003",
"category": "microblog",
"content": "<p>Hello, <a href=\"https://b.example/users/034de9r4fr006\" data-mention=\"b.example:034de9r4fr006\">@joe@b.example</a>! How are you doing today?</p>",
"visibility": "public",
"is_sensitive": false,
"mentions": [
"b.example:034de9r4fr006"
],
"previews": []
}
It is now time for a.example to send the note to joe.
Sending the Note
a.example sends the note to the inbox of b.example, which hosts joe. note.json holds the note above, with no trailing newline.
# The request is signed by a.example's instance private key
curl -X POST https://b.example/.versia/v0.7/inbox \
--data-binary @note.json \
-H "Content-Type: application/vnd.versia+json" \
-H "User-Agent: CoolServer/1.0 (https://coolserver.example)" \
-H "Versia-Signature: n+9b5vDR1CcvoxaO+XhWUj6hlVRQeZ+t+EC31SJHD8qHJQ7Y6yd8ZzgrJi9uOWnb7t3ht0EWVa2qF82Jq7ZlCQ==" \
-H "Versia-Signed-By: a.example" \
-H "Versia-Signed-At: 1733051946"
b.example verifies the signature with the key it already has, and responds with a 202 Accepted status code.
Displaying the Note
The software on b.example processes the note and shows it to joe using whatever interface it has.
joe can now see the note from @alice on a.example and respond to it.