@@ -5,11 +5,11 @@ description: >-
55---
66
77Relay
8- ============
8+ =====
99
1010* This API is available since Fedify 2.0.0.*
1111
12- Fedify provides the ` @fedify/relay ` package for building [ ActivityPub relay
12+ Fedify provides the * @fedify/relay * package for building [ ActivityPub relay
1313servers] —services that forward activities between instances without requiring
1414individual actor-following relationships.
1515
@@ -19,16 +19,24 @@ individual actor-following relationships.
1919Setting up a relay server
2020-------------------------
2121
22- First, install the ` @fedify/relay ` package.
22+ First, install the * @fedify/relay * package.
2323
2424::: code-group
2525
2626~~~~ sh [Deno]
2727deno add @fedify/relay
2828~~~~
2929
30- ~~~~ sh [Node.js]
31- npm add @fedify/relay
30+ ~~~~ sh [npm]
31+ npm add @fedify/relay @hono/node-server
32+ ~~~~
33+
34+ ~~~~ sh [pnpm]
35+ pnpm add @fedify/relay @hono/node-server
36+ ~~~~
37+
38+ ~~~~ sh [Yarn]
39+ yarn add @fedify/relay @hono/node-server
3240~~~~
3341
3442~~~~ sh [Bun]
@@ -39,7 +47,9 @@ bun add @fedify/relay
3947
4048Then create a relay using the ` createRelay() ` function.
4149
42- ~~~~ typescript twoslash
50+ ::: code-group
51+
52+ ~~~~ typescript twoslash [Deno]
4353import { createRelay } from " @fedify/relay" ;
4454import { MemoryKvStore } from " @fedify/fedify" ;
4555
@@ -48,24 +58,69 @@ const relay = createRelay("mastodon", {
4858 domain: " relay.example.com" ,
4959 name: " My ActivityPub Relay" ,
5060 subscriptionHandler : async (ctx , actor ) => {
51- // Approve all subscriptions
61+ // Approve all subscriptions
5262 return true ;
5363 },
5464});
5565
5666Deno .serve ((request ) => relay .fetch (request ));
5767~~~~
5868
69+ ~~~~ typescript twoslash [Bun]
70+ import " @types/bun" ;
71+ // ---cut-before---
72+ import { createRelay } from " @fedify/relay" ;
73+ import { MemoryKvStore } from " @fedify/fedify" ;
74+
75+ const relay = createRelay (" mastodon" , {
76+ kv: new MemoryKvStore (),
77+ domain: " relay.example.com" ,
78+ name: " My ActivityPub Relay" ,
79+ subscriptionHandler : async (ctx , actor ) => {
80+ // Approve all subscriptions
81+ return true ;
82+ },
83+ });
84+
85+ Bun .serve ({
86+ port: 8000 ,
87+ fetch(request ) {
88+ return relay .fetch (request );
89+ },
90+ });
91+ ~~~~
92+
93+ ~~~~ typescript twoslash [Node.js]
94+ import { createRelay } from " @fedify/relay" ;
95+ import { MemoryKvStore } from " @fedify/fedify" ;
96+ import { serve } from " @hono/node-server" ;
97+
98+ const relay = createRelay (" mastodon" , {
99+ kv: new MemoryKvStore (),
100+ domain: " relay.example.com" ,
101+ name: " My ActivityPub Relay" ,
102+ subscriptionHandler : async (ctx , actor ) => {
103+ // Approve all subscriptions
104+ return true ;
105+ },
106+ });
107+
108+ serve ({
109+ port: 8000 ,
110+ fetch(request ) {
111+ return relay .fetch (request );
112+ },
113+ });
114+ ~~~~
115+
116+ :::
117+
59118> [ !WARNING]
60119> ` MemoryKvStore ` is for development only. For production, use a persistent
61- > store like ` RedisKvStore ` from [ ` @fedify/redis ` ] , ` PostgresKvStore ` from
62- > [ ` @fedify/postgres ` ] , or ` DenoKvStore ` from [ ` @fedify/denokv ` ] .
120+ > store like ` RedisKvStore ` from * @fedify/redis * , ` PostgresKvStore ` from
121+ > * @fedify/postgres * , or ` DenoKvStore ` from * @fedify/denokv * .
63122>
64- > See the [ * Key-value store* section] ( ./kv.md ) for details.
65-
66- [ `@fedify/redis` ] : https://github.com/fedify-dev/fedify/tree/main/packages/redis
67- [ `@fedify/postgres` ] : https://github.com/fedify-dev/fedify/tree/main/packages/postgres
68- [ `@fedify/denokv` ] : https://github.com/fedify-dev/fedify/tree/main/packages/denokv
123+ > See the [ * Key–value store* section] ( ./kv.md ) for details.
69124
70125
71126Configuration options
@@ -105,7 +160,8 @@ Configuration options
105160
106161` subscriptionHandler ` (required)
107162: Callback to approve or reject subscription requests. See
108- [ * Handling subscriptions* ] ( #handling-subscriptions ) . To create an open relay that accepts all subscriptions:
163+ [ * Handling subscriptions* ] ( #handling-subscriptions ) . To create an open relay
164+ that accepts all subscriptions:
109165
110166 ~~~~ typescript
111167 subscriptionHandler: async (ctx, actor) => true
@@ -124,14 +180,17 @@ Configuration options
124180Relay types
125181-----------
126182
127- The first parameter to ` createRelay() ` specifies the relay protocol:
183+ The first parameter to ` createRelay() ` specifies the relay protocol.
184+ For detailed protocol specifications, see [ FEP-ae0c] .
185+
186+ [ FEP-ae0c ] : https://w3id.org/fep/ae0c
128187
129- | Feature | ` "mastodon" ` | ` "litepub" ` |
130- | ---------| --------------| -------------|
131- | Activity forwarding | Direct | Wrapped in ` Announce ` |
132- | Following relationship | One-way | Bidirectional |
133- | Subscription state | Immediate ` "accepted" ` | ` "pending" ` → ` "accepted" ` |
134- | Compatibility | Broad (most implementations) | LitePub-aware servers |
188+ | Feature | ` "mastodon" ` | ` "litepub" ` |
189+ | ------------------------ | ------------------------------ | ----------------- -------------|
190+ | Activity forwarding | Direct | Wrapped in ` Announce ` |
191+ | Following relationship | One-way | Bidirectional |
192+ | Subscription state | Immediate ` "accepted" ` | ` "pending" ` → ` "accepted" ` |
193+ | Compatibility | Broad (most implementations) | LitePub-aware servers |
135194
136195> [ !TIP]
137196> Use ` "mastodon" ` for broader compatibility. Switch to ` "litepub" ` only if
@@ -157,7 +216,7 @@ Forwards `Create`, `Update`, `Delete`, `Move`, and `Announce` activities.
157216
158217### LitePub-style relay
159218
160- The relay server follows back instances that subscribe to it. Forwarded
219+ The relay server follows back instances that subscribe to it. Forwarded
161220activities are wrapped in ` Announce ` objects.
162221
163222~~~~ typescript twoslash
@@ -172,6 +231,58 @@ const relay = createRelay("litepub", {
172231~~~~
173232
174233
234+ Subscribing to a relay
235+ ----------------------
236+
237+ Instance administrators can subscribe to your relay by adding the relay URL
238+ in their server settings. The URL format differs depending on the relay type.
239+
240+ ### Subscription URL
241+
242+ The subscription URL differs between Mastodon-style and LitePub-style relays:
243+
244+ | Relay type | Subscription URL | Example |
245+ | --------------| ----------------------------------------| -----------------------------------|
246+ | ` "mastodon" ` | Inbox URL: ` https://{domain}/inbox ` | ` https://relay.example.com/inbox ` |
247+ | ` "litepub" ` | Actor URL: ` https://{domain}/actor ` | ` https://relay.example.com/actor ` |
248+
249+ For more details on the protocol differences, see [ FEP-ae0c] .
250+
251+ ### Subscribing from Mastodon
252+
253+ To subscribe from a Mastodon instance:
254+
255+ 1 . Go to ** Preferences** → ** Administration** → ** Relays**
256+ 2 . Click ** Add new relay**
257+ 3 . Enter the relay inbox URL (e.g., ` https://relay.example.com/inbox ` )
258+ 4 . Click ** Save and enable**
259+
260+ The relay will receive a ` Follow ` activity from the instance. If the
261+ ` subscriptionHandler ` approves the request, the relay sends back an ` Accept `
262+ activity, and the instance becomes a subscriber.
263+
264+ > [ !NOTE]
265+ > Mastodon only supports Mastodon-style relays. Use the inbox URL
266+ > (` https://{domain}/inbox ` ) when subscribing from Mastodon.
267+
268+ ### Subscribing from Pleroma/Akkoma
269+
270+ Pleroma and Akkoma use LitePub-style relays by default. To subscribe:
271+
272+ 1 . Use the admin CLI or MIX task to add the relay
273+ 2 . Enter the relay actor URL (e.g., ` https://relay.example.com/actor ` )
274+
275+ ### Subscribing from other software
276+
277+ Consult your server software's documentation for specific instructions.
278+ The general process is:
279+
280+ 1 . Find the relay settings in your server's administration panel
281+ 2 . Add the appropriate relay URL (inbox URL for Mastodon-style, actor URL
282+ for LitePub-style)
283+ 3 . Wait for the subscription to be approved
284+
285+
175286Handling subscriptions
176287----------------------
177288
@@ -293,10 +404,10 @@ Stored with keys `["follower", actorId]`. Actor objects typically range from
293404
294405Two key pairs are generated and stored:
295406
296- | Key | Purpose |
297- | -----| ---------|
298- | ` ["keypair", "rsa", "relay"] ` | HTTP Signatures |
299- | ` ["keypair", "ed25519", "relay"] ` | Linked Data Signatures, Object Integrity Proofs |
407+ | Key | Purpose |
408+ | ------------------------------------ | ----------------------------------------- ---------|
409+ | ` ["keypair", "rsa", "relay"] ` | HTTP Signatures |
410+ | ` ["keypair", "ed25519", "relay"] ` | Linked Data Signatures, Object Integrity Proofs |
300411
301412> [ !NOTE]
302413> These keys are critical for the relay's identity. Back up your ` KvStore `
@@ -366,21 +477,21 @@ await configure({
366477
367478Key log categories:
368479
369- | Category | Description |
370- | ----------| -------------|
371- | ` ["fedify", "federation", "inbox"] ` | Incoming activities |
372- | ` ["fedify", "federation", "outbox"] ` | Outgoing activities |
373- | ` ["fedify", "sig"] ` | Signature verification |
480+ | Category | Description |
481+ | ---------------------------------------- | ----------- -------------|
482+ | ` ["fedify", "federation", "inbox"] ` | Incoming activities |
483+ | ` ["fedify", "federation", "outbox"] ` | Outgoing activities |
484+ | ` ["fedify", "sig"] ` | Signature verification |
374485
375486### OpenTelemetry
376487
377488The relay supports [ OpenTelemetry] ( ./opentelemetry.md ) tracing. Key spans:
378489
379- | Span | Description |
380- | ------| -------------|
381- | ` activitypub.inbox ` | Receiving activities |
382- | ` activitypub.send_activity ` | Forwarding activities |
383- | ` activitypub.dispatch_inbox_listener ` | Processing inbox events |
490+ | Span | Description |
491+ | ----------------------------------------- | ------------- -------------|
492+ | ` activitypub.inbox ` | Receiving activities |
493+ | ` activitypub.send_activity ` | Forwarding activities |
494+ | ` activitypub.dispatch_inbox_listener ` | Processing inbox events |
384495
385496
386497<!-- cSpell: ignore LitePub -->
0 commit comments