# Federation

How entities reach other instances: inboxes, delivery, access and ordering.

This page describes how instances in a Versia network exchange data.

Federation is built on the [HyperText Transfer Protocol (HTTP)](https://datatracker.ietf.org/doc/html/rfc9110) and the [JavaScript Object Notation (JSON)](https://datatracker.ietf.org/doc/html/rfc8259) data format. Instances communicate with each other by sending and receiving JSON payloads over HTTP.

## Related Pages

- [Discovery](/federation/discovery): How Versia instances can discover users, capabilities, and public keys.
- [Versions](/federation/versions): How instances choose a protocol version.
- [HTTP](/federation/http): Rules for HTTP communication in Versia.
- [Endpoints](/federation/endpoints): Every route instances serve.
- [Validation](/validation): Validation rules for Versia implementations.
- [Implementing a Receiver](/guides/implementing-a-receiver): The checks an inbox runs on each request.

## Inboxes

Every [Instance](/entities/instance-metadata) has one HTTP endpoint called an inbox (`/.versia/v0.7/inbox`), which receives messages for all of its users. Messages are sent to it as JSON payloads over HTTP `POST` requests. See the [Inbox Endpoint](/federation/endpoints#inbox).

> The closest ActivityPub equivalent is the shared inbox. Versia has no inbox for each user, and sends entities without wrapping them in activities. See [Other Protocols](/other-protocols#no-activity-wrapper).

Let's consider the following example:

Alice, on the instance `alice.example`, sends a message to Bob on the instance `bob.example`.

To perform this action, Alice's instance sends a `POST` request to Bob's instance's inbox endpoint. This request contains the entity that Alice wants to send to Bob, such as a [Note](/extensions/social#note), with [the appropriate metadata](/federation/http) to ensure the message is valid.

Bob's instance receives the message and processes it according to the rules defined in the [Validation](/validation) document.

## Delivery

A sender **MUST** deliver each entity to the instances hosting the users below. It **MAY** also deliver it to other instances that [may fetch it](#access), and **MAY** skip instances it refuses to federate with.

| Entity                                                                                       | Delivered to           |
| -------------------------------------------------------------------------------------------- | ---------------------- |
| [User](/entities/user), after a change                                                       | The user's subscribers |
| [Subscribe](/entities/subscribe), [Unsubscribe](/entities/unsubscribe)                       | The target             |
| [SubscribeAccept](/entities/subscribe-accept), [SubscribeReject](/entities/subscribe-reject) | The subscriber         |

[Changing an entity](/entities#changing-an-entity) or sending a [Delete](/entities/delete) for it goes to the same audience, as it stands at that moment.

Extensions state the delivery rules for their own entities on their own pages.

## Access

Requests identify an instance, not a user, so access is decided per instance. An instance **MUST NOT** serve an entity to an instance that may not fetch it, and **MUST** answer such a request with a `404 Not Found` status code, so as not to reveal that the entity exists.

| Entity                 | May be fetched by |
| ---------------------- | ----------------- |
| [User](/entities/user) | Any instance      |

An instance that fetches an entity **MUST** apply the same limits to its own users.

[Collections](/structures/collection) list only the items the requesting instance may fetch. [Transient entities](/entities#transient-entities) cannot be fetched at all. Extensions state the access rules for their own entities on their own pages. An extension **MAY** add to who can fetch an entity, and **MUST** state it on its page. It **MUST NOT** take anyone away.

## Ordering

Delivery order is not guaranteed. An instance can receive a [Like](/extensions/likes) before the [Note](/extensions/social#note) it refers to.

A receiver **SHOULD** fetch referenced entities it does not have. If it cannot, it **MAY** retry later or drop the entity.

An entity with nothing to apply to, such as a [SubscribeAccept](/entities/subscribe-accept) with no pending request, **MUST** be ignored, and is not an error.
