Other Protocols
This page is for readers who already know ActivityPub or the Matrix server-server API. It maps Versia’s concepts to theirs and explains where they differ. It is informative and sets no requirements: the linked pages define the protocol.
Some ActivityPub practice comes from Mastodon and other implementations rather than from the ActivityPub specification. This page says so where it matters.
Concepts
| Versia | ActivityPub | Matrix |
|---|---|---|
| Instance | Server | Homeserver |
| Entity | Object or Activity | Event |
| Reference | id, a URL | Event ID |
| User address | WebFinger address, by convention | User ID |
| Inbox, one per instance | Inbox per actor, optional shared inbox | Transactions |
| Signature by the instance key | HTTP Signatures by an actor key, by convention | X-Matrix header, by a server key |
| Extension names | JSON-LD contexts | Namespaced event types |
| Subscribe | Follow | None |
| Changing an entity | Update | Event replacements |
| Delete | Delete and Tombstone | Redaction |
| Collection | Collection | None |
| Versions | None | Spec and endpoint versions |
| Discovery | WebFinger, by convention | Well-known file |
| Versia Links | None | matrix: URIs and matrix.to links |
No Activity Wrapper
ActivityPub delivers activities, such as a Create that wraps a Note. Versia sends the entity itself: an instance posts a Note by sending the Note to the inbox. Actions that have no object to send are their own entities, such as Subscribe and Delete.
To change an entity, an instance sends the whole entity again with the same id. This matches ActivityPub’s server-to-server Update, which replaces the whole object.
Plain JSON and Namespaces
Versia is plain JSON, like Matrix, and not JSON-LD. Extensions are named by the reverse domain of their author, such as pub.versia:likes, and pub.versia is reserved for this specification. Matrix does the same with event types, such as com.example.myapp.event, with m. reserved for its specification.
A receiver ignores unknown fields. It answers an entity of an unknown extension type with a 2xx and drops it.
Instance Keys
ActivityPub does not define authentication. In practice, servers sign requests with HTTP Signatures, using a key that belongs to an actor. Versia signs requests and responses between instances with one key per instance, published in its InstanceMetadata. This is closest to Matrix, where a homeserver signs requests with its own key.
Signed Messages, Not Signed Entities
Matrix signs each event, so a server can check an event that another server passes on. Versia signs the HTTP message, not the entity. An entity’s author must belong to the instance that signed the message, so an instance cannot pass on another instance’s entities.
This is why, in Groups, the group’s instance tells members’ instances to fetch a Note from its author’s instance instead of forwarding it.
Subscriptions
Subscribe, SubscribeAccept, SubscribeReject and Unsubscribe play the roles of ActivityPub’s Follow, Accept, Reject and Undo of a Follow. A Subscribe can target any entity type that accepts subscriptions, such as a Group, not only a User.
Matrix has no subscription to a user. Users join rooms, and every server in a room holds a copy of it. A Versia Group lives on one instance instead, which tells members’ instances what is posted to it.
Posts
Versia’s core has no post type. Posts are Notes from the Social extension, which most other extensions build on. In ActivityPub, Note is part of the ActivityStreams vocabulary, and in Matrix, messages are m.room.message events.
| Versia | ActivityPub |
|---|---|
| Note | Note |
| Notes collection | Outbox |
| Featured collection | featured, by Mastodon convention |
Note mentions | Mention tags |
Note subject and is_sensitive | summary and sensitive, by Mastodon convention |
| Share | Announce |
| Like and Dislike | Like and Dislike |
| Reactions | None in ActivityStreams |
| Polls | Question |
| Migration | Move |