-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.html
1056 lines (832 loc) · 69.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en" dir="ltr" typeof="bibo:Document " prefix="bibo: http://purl.org/ontology/bibo/ w3p: http://www.w3.org/2001/02pd/rec54#">
<head><meta lang="" property="dc:language" content="en">
<title>Social Web Protocols</title>
<meta charset="utf-8">
<style>/*****************************************************************
* ReSpec 3 CSS
* Robin Berjon - http://berjon.com/
*****************************************************************/
/* --- INLINES --- */
em.rfc2119 {
text-transform: lowercase;
font-variant: small-caps;
font-style: normal;
color: #900;
}
h1 acronym, h2 acronym, h3 acronym, h4 acronym, h5 acronym, h6 acronym, a acronym,
h1 abbr, h2 abbr, h3 abbr, h4 abbr, h5 abbr, h6 abbr, a abbr {
border: none;
}
dfn {
font-weight: bold;
}
a.internalDFN {
color: inherit;
border-bottom: 1px solid #99c;
text-decoration: none;
}
a.externalDFN {
color: inherit;
border-bottom: 1px dotted #ccc;
text-decoration: none;
}
a.bibref {
text-decoration: none;
}
cite .bibref {
font-style: normal;
}
code {
color: #C83500;
}
/* --- TOC --- */
.toc a, .tof a {
text-decoration: none;
}
a .secno, a .figno {
color: #000;
}
ul.tof, ol.tof {
list-style: none outside none;
}
.caption {
margin-top: 0.5em;
font-style: italic;
}
/* --- TABLE --- */
table.simple {
border-spacing: 0;
border-collapse: collapse;
border-bottom: 3px solid #005a9c;
}
.simple th {
background: #005a9c;
color: #fff;
padding: 3px 5px;
text-align: left;
}
.simple th[scope="row"] {
background: inherit;
color: inherit;
border-top: 1px solid #ddd;
}
.simple td {
padding: 3px 10px;
border-top: 1px solid #ddd;
}
.simple tr:nth-child(even) {
background: #f0f6ff;
}
/* --- DL --- */
.section dd > p:first-child {
margin-top: 0;
}
.section dd > p:last-child {
margin-bottom: 0;
}
.section dd {
margin-bottom: 1em;
}
.section dl.attrs dd, .section dl.eldef dd {
margin-bottom: 0;
}
@media print {
.removeOnSave {
display: none;
}
}
</style><style>/* --- EXAMPLES --- */
div.example-title {
min-width: 7.5em;
color: #b9ab2d;
}
div.example-title span {
text-transform: uppercase;
}
aside.example, div.example, div.illegal-example {
padding: 0.5em;
margin: 1em 0;
position: relative;
clear: both;
}
div.illegal-example { color: red }
div.illegal-example p { color: black }
aside.example, div.example {
padding: .5em;
border-left-width: .5em;
border-left-style: solid;
border-color: #e0cb52;
background: #fcfaee;
}
aside.example div.example {
border-left-width: .1em;
border-color: #999;
background: #fff;
}
aside.example div.example div.example-title {
color: #999;
}
table.th90 th {
height: 140px;
white-space: nowrap;
transform:
rotate(-90deg);
max-width: 4em;
}
table.th90 th, table.th90 td {
text-align: center;
}
</style><!--[if lt IE 9]><script src='https://www.w3.org/2008/site/js/html5shiv.js'></script><![endif]-->
<script src='https://www.w3.org/Tools/respec/respec-w3c-common' async class='remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "ED",
shortName: "social-web-protocols",
otherLinks: [
{
"key": "Repository",
"data": [
{
"value": "Git repository",
"href": "https://github.com/w3c-social/social-web-protocols",
},
{
"value": "Issues",
"href": "https://github.com/w3c-social/social-web-protocols/issues",
},
{
"value": "Commits",
"href": "https://github.com/w3c-social/social-web-protocols/gh-pages",
}
]
}
],
editors: [
{ name: "Amy Guy",
url: "http://rhiaro.co.uk/",
company: "University of Edinburgh",
companyURL: "http://inf.ed.ac.uk/",
mailto: "[email protected]",
w3cid: "69000" }
],
previousMaturity: "WD",
previousPublishDate: "2017-05-04",
edDraftURI: "https://w3c-social.github.io/social-web-protocols",
wg: "Social Web Working Group",
wgURI: "https://www.w3.org/Social/WG",
wgPublicList: "public-socialweb",
wgPatentURI: "https://www.w3.org/2004/01/pp-impl/72531/status",
localBiblio: {
"AS1": {
title: "JSON Activity Streams 1.0.",
href: "http://activitystrea.ms/specs/json/1.0/",
authors: ["J. Snell", "M. Atkins", "W. Norris", "C. Messina", "M. Wilkinson", "R. Dolin"],
status: "Unofficial",
publisher: "http://activitystrea.ms"
},
"microformats2": {
title: "Microformats2",
href: "https://microformats.org/wiki/microformats2",
authors: ["Tantek Çelik"],
status: "Living specification",
publisher: "https://microformats.org"
},
"IndieAuth": {
title: "IndieAuth",
href: "https://www.w3.org/TR/indieauth",
authors: ["Aaron Parecki"],
status: "Note",
publisher: "W3C"
},
"Accept-Post": {
title: "The Accept-Post HTTP Header.",
href: "http://tools.ietf.org/html/draft-wilde-accept-post",
authors: ["J. Arwe", "S. Speicher", "E. Wilde"],
status: "Internet Draft",
publisher: "IETF"
},
}
};
</script>
</head>
<body>
<section id="abstract">
The Social Web Protocols are a collection of standards which enable various aspects of decentralised social interaction on the Web. This document describes the purposes of each, and how they fit together.
</section>
<section id="sotd"></section>
<section id="introduction">
<h2>Introduction</h2>
<p>The W3C Social Web Working Group ran from June 2014 to December 2017, published seven recommendations and some notes. This is one of the notes, and it describes the work at the time of the group closing.</p>
<p>This work is by no means done, and the various communities involved have by no means gone to sleep. The endeavour continues in the <a href="https://www.w3.org/wiki/SocialCG">Social Web Community Group</a>, in which you are warmly invited to particiate.</p>
</section>
<section id="overview">
<h2>Overview</h2>
<p>People and the content they create are the core components of the social web; they make up the social graph. This document describes a standard way in which people can:</p>
<ul>
<li>create, update and delete social content;</li>
<li>connect with other people by subscribing to their content;</li>
<li>interact with other peoples' content;</li>
<li>be notified when other people interact with their content.</li>
</ul>
<p>regardless of <em>what that content</em> is or <em>where it is stored</em>.</p>
<p>These components are core building blocks for interoperable decentralised social systems.</p>
<p>Each of these components can be implemented independently as needed, or all together in one system, as well as extended to meet domain-specific requirements. Users can store their social data across any number of compliant servers, and use compliant clients hosted elsewhere to interact with their own content and the content of others.</p>
<p>The <a href="https://www.w3.org/2013/socialweb/social-wg-charter">Social Web Working Group Charter</a> proposes the following deliverables, which have been met by the Group, and will be referred to throughout this document:</p>
<dl>
<dt>Social Data Syntax</dt>
<dd>A JSON-based syntax to allow the transfer of social information, such as status updates, across differing social systems.</dd>
<dt>Social API</dt>
<dd>A document that defines a specification for a client-side API that lets developers embed and format third party information such as social status updates.</dd>
<dt>Federation Protocol</dt>
<dd>A Web protocol to allow the federation of activity-based status updates and other data (such as profile information) between heterogeneous Web-based social systems. Federation should include multiple servers sharing updates within a client-server architecture, and allow decentralized social systems to be built.</dd>
</dl>
<section id="contents">
<h3>Contents</h3>
<p>This is an overview of the specifications of the Social Web Working Group.</p>
<p>Due to the diversity of viable technical approaches proposed within the Working Group, several specifications reached recommendation which provide overlapping functionality through differing mechanisms. This document exists to provide informative guidance on how and when to implement the various specifications, as well as some hints towards routes to bridging between similar specifications.</p>
</section>
<section id="definitions">
<h3>Definitions</h3>
<p>This document is divided into five sections, pertaining to the components above, and derived from the <a href="https://www.w3.org/wiki/Socialwg/Social_API/Requirements">Social API Requirements</a>. The various Social Web Working Group specifications implement different combinations of these requirements (see <a href="#requirements"></a>) so for clarity the requirement are defined here.</p>
<dl>
<dt><a href="#reading">reading</a></dt>
<dd>covers specifications which describe the syntax and vocabulary to be used for social content. Useful for applications which expose feeds, as well as those which consume them.</dd>
<dt>publishing</dt>
<dd>covers Social API specifications which tell clients how to instruct servers to <a href="#publishing">create</a>, <a href="#updating">update</a> or <a href="#deleting">delete</a> content.</dd>
<dt><a href="#subscribing">subscribing</a></dt>
<dd>covers Federation Protocol specifications which describe how to ask for notifications about content, and subsequently how those notifications should be delivered.</dd>
<dt><a href="#delivery">delivery</a></dt>
<dd>covers Federation Protocol specifications which describe how to deliver notifications which have not been solicited through subscription.</dd>
<dt><a href="#profiles">profiles</a></dt>
<dd>covers specifications which describe profiles.</dd>
</dl>
</section>
<section id="swwg-specs">
<h3>Specifications</h3>
<p>These are the specifications produced by the Social Web Working Group. New implementation reports and feedback are always welcome (details for where to submit these are at the top of each document).</p>
<dl>
<dt>[[Activitypub]]</dt>
<dd>JSON(-LD)-based APIs for client-to-server interactions (ie. publishing) and server-to-server interactions (ie. federation).</dd>
<dt>ActivityStreams 2.0 [[activitystreams-core]] and [[activitystreams-vocabulary]]</dt>
<dd>The syntax and vocabulary for <a href="#reading">representing</a> social activities, actors, objects, and collections in JSON(-LD).</dd>
<dt>Linked Data Notifications ([[LDN]])</dt>
<dd>A JSON-LD-based protocol for <a href="#delivery">delivery</a>.</dd>
<dt>[[Micropub]]</dt>
<dd>A form-encoding and JSON-based API for client-to-server interactions (ie. publishing).</dd>
<dt>[[Webmention]]</dt>
<dd>A form-encoding-based protocol for <a href="#delivery">delivery</a>.</dd>
<dt>[[WebSub]]</dt>
<dd>A protocol for <a href="#subscribing">subscription</a> to any resource and <a href="#delivery">delivery</a> of updates about it.</dd>
</dl>
<p>Specifications which are not Social Web Working Group recommendations, but which are nonetheless relevent to the charter deliverables, are described in <a href="#related-specs"></a>.</p>
<section id="requirements">
<h4>Requirements</h4>
<p>This table shows the high level requirements according to the <a href="https://www.w3.org/2013/socialweb/social-wg-charter.html">Social Web Working Group charter</a> and the <a href="https://www.w3.org/wiki/Socialwg/Social_API/Requirements">Social API Requirements</a>, and how the specifications of the Working Group overlap with respect to each.</p>
<p>This table lists the requirements met by the core functionality of each specification. Some specifications may additionally touch on or make suggestions about other requirements, which can be useful when deciding how to combine specifications, and is highlighted as appropriate throughout this document.</p>
<table class="th90">
<tr>
<td></td>
<td colspan="3">Data syntax</td>
<td colspan="4">Social API</td>
<td colspan="2">Federation Protocol</td>
<td></td>
</tr>
<tr>
<th></th>
<th><a href="#content-representation">Vocabulary</a></th>
<th><a href="#content-representation">Syntax</a></th>
<th><a href="#profiles">Profiles</a></th>
<th><a href="#reading">Read</a></th>
<th><a href="#publishing">Create</a></th>
<th><a href="#updating">Update</a></th>
<th><a href="#deleting">Delete</a></th>
<th><a href="#subscribing">Subscription</a></th>
<th><a href="#delivery">Delivery</a></th>
</tr>
<tr>
<td style="text-align:left;">ActivityPub</td>
<td></td>
<td></td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
</tr>
<tr>
<td style="text-align:left;">ActivityStreams 2.0</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td style="text-align:left;">Linked Data Notifications</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
</tr>
<tr>
<td style="text-align:left;" style="text-align:left;">Micropub</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<td>X</td>
<td>X</td>
<td></td>
<td></td>
</tr>
<tr>
<td style="text-align:left;">Webmention</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
</tr>
<tr>
<td style="text-align:left;">WebSub<br></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>X</td>
<td></td>
</tr>
</table>
</section>
<section id="how-do-the-specs-relate-to-each-other">
<h4>How do these specifications relate to each other?</h4>
<p>As a quick reference, some key relationships between specifications are as follows:</p>
<ul>
<li><strong>ActivityPub and ActivityStreams 2.0</strong>: ActivityPub uses the AS2 syntax and vocabulary for the payload of all requests.</li>
<li><strong>ActivityPub and Linked Data Notifications</strong>: ActivityPub specialises LDN as the mechanism for delivery of notifications by requiring that payloads are AS2. <em>Inbox</em> endpoint discovery is the same. LDN receivers can understand requests from ActivityPub federated servers, but ActivityPub servers can't necessarily understand requests from generic LDN senders.</li>
<li><strong>ActivityStreams 2.0 and Linked Data Notifications</strong>: LDN MAY use the AS2 syntax and vocabulary for the payload of notification requests.</li>
<li><strong>Webmention and Linked Data Notifications</strong>: Overlapping functionality that needs to be bridged due to different content types of requests. An LDN request MAY contain the equivalent data as a Webmention request, but not necessarily vice versa.</li>
<li><strong>ActivityPub and Micropub</strong>: Overlapping functionality that needs to be bridged due to different vocabularies and possibly different content types of requests. Micropub specifies client-to-server interactions for content creation; ActivityPub specifies this, <em>plus</em> side-effects and server-to-server interactions.</li>
<li><strong>Micropub and Webmention</strong>: Are complementary but independent. Content can be created with Micropub, then Webmentions can be sent to any URLs referenced by the content.</li>
<li><strong>Micropub and Linked Data Notifications</strong>: Are complementary but independent. Content can be created with Micropub, then LDN discovery can be commenced on any relevant resources referenced by the content.</li>
<li><strong>Micropub and WebSub</strong>: Are complementary but independent. Content can be created with Micropub, then a WebSub <em>hub</em> can handle delivery to subscribers.</li>
<li><strong>ActivityPub and WebSub</strong>: Overlapping functionality using different content types and verification mechanisms.</li>
</ul>
</section>
</section>
</section>
<section id="reading">
<h2>Reading</h2>
<p>If you are a content publisher, this section is about how you should publish your content. If you are a content consumer, this is what you should expect to consume.</p>
<section id="content-representation">
<h3>Content representation</h3>
<p><strong>ActivityStreams 2.0</strong> is the recommended syntax ([[activitystreams-core]]) and vocabulary ([[activitystreams-vocabulary]]) for social data. ActivityStreams 2.0 represents content and interactions as <em>Objects</em> and <em>Activities</em>. The ActivityStreams vocabulary defines a finite set of common Object and Activity types and properties, as well as an extension mechanism for applications which want to expand on or specialise these.</p>
<p>ActivityStreams 2.0 content is served with the Content-Type <code>application/activity+json</code> or for JSON-LD extended implementations, <code>application/ld+json; profile="https://www.w3.org/ns/activitystreams"</code>. Consumers should recognise both of these Content-Types as ActivityStreams 2.0; <span title="after much wringing of hands and gnashing of teeth, the WG decided that">they should be treated as equivalent</span>.</p>
<p>In order to claim ActivityStreams 2.0 conformance, a data publisher must use ActivityStreams 2.0 vocabulary terms where available, and <em>only</em> use other vocabularies <em>in addition</em>, or where no appropriate ActivityStreams 2.0 term exists.</p>
<p class="note" title="ActivityStreams 1.0">ActivityStreams 2.0 builds upon [[AS1]] and is not fully backwards compatible; <a href="http://www.w3.org/TR/activitystreams-core#activitystreams-1.0">the relationship between AS1 and AS2 is documented in the AS2 spec</a>. If you have implemented [[AS1]], you should transition to ActivityStreams 2.0.</p>
<p>To make content available as ActivityStreams 2.0 JSON, one could do so directly when requested with an appropriate <code>Accept</code> header (eg. <code>application/activity+json</code> or <code>application/ld+json</code>), or indirectly via a <code>rel="alternate" type="application/activity+json"</code> link . This link could be to a different domain, for third-party services which dynamically generate ActivityStreams 2.0 JSON on behalf of a publisher.</p>
<div class="note" title="JSON-LD">
<p>When sent as JSON-LD, ActivityStreams 2.0 must be <a href="https://json-ld.org/spec/latest/json-ld-api/#compaction">compacted</a>, and must not use the <code>@graph</code> keyword. This is because an ActivityStreams 2.0 document requires a single <code>Object</code> as the root. To serve multiple resources, you can instead nest them.</p>
<p>The <a href="https://www.w3.org/ns/activitystreams#">ActivityStreams 2.0 JSON-LD context</a> (https://www.w3.org/ns/activitystreams#) aliases <code>@id</code> and <code>@type</code> to <code>id</code> and <code>type</code> respectively.</p>
</div>
<p><strong>[[Activitypub]]</strong> uses ActivityStreams 2.0 for all data, and also <em>extends</em> ActivityStreams 2.0 with additional terms. Thus, ActivityPub requires responses to have the Content-Type <code>application/ld+json; profile="https://www.w3.org/ns/activitystreams"</code>. Publishers are however expected to also respect requests with the <code>application/activity+json</code> Accept header.</p>
<section id="content-other">
<h4>Other ways of representing content</h4>
<p>If you don't like ActivityStreams 2.0, there are still some specifications you can use for particular tasks.</p>
<p><strong>[[LDN]]</strong> notification contents can use any vocabulary, so long as the data is available as JSON-LD. Thus notifications MAY use ActivityStreams 2.0, but don't have to.</p>
<p><strong>[[Micropub]]</strong> clients which expect to read data (this would usually be clients for <em><a href="#updating">updating</a></em>) are expecting it as JSON in the parsed microformats2 syntax ([[microformats2-parsing]]).</p>
<p><strong>[[WebSub]]</strong> is agnostic as to the Content-Type used by publishers; hubs are expected to deliver the new content to subscribers as-is produced by the publisher, at the publisher's <code>topic</code> URL.</p>
</section>
</section>
<section id="objects">
<h3>Objects</h3>
<p>All ActivityStreams 2.0 objects have URLs in the <code>id</code> property, which return the properties of an object. The response may vary depending on the requester's right to access the content.</p>
</section>
<section id="collections">
<h3>Collections</h3>
<p>Each ActivityStreams 2.0 collection has a URL in the <code>id</code> property which returns the contents of the stream (according to the requester's right to access). This could be paged - ActivityStreams 2.0 provides <a href="https://www.w3.org/TR/activitystreams-core/#paging">a paging mechanism</a>. It may include additional metadata about the stream (such as title, description).</p>
<p>Each <a href="#objects">object</a> in a collection contains at least its URL (<code>id</code>), as well as optionally other properties of the object.</p>
<p>Collections may represent changing streams of objects, or fixed sets. One <a href="#profiles">profile</a> may be associated with one or more streams of content. Streams may be generated automatically or manually, and might be segregated by post type, topic, audience, or any arbitrary criteria decided by the curator of the stream. A profile may include links to multiple streams, which a consumer could follow to read or subscribe to.</p>
<section id="streams-special">
<h4>Special streams</h4>
<p><strong>[[Activitypub]]</strong> specifies two streams that MUST be accessible from a profile via the following properties:</p>
<ul>
<li><code>inbox</code>: A reference to an ActivityStreams 2.0 collection comprising all the objects received by the actor.</li>
<li><code>outbox</code>: An ActivityStreams 2.0 collection comprising all the objects produced by the actor.</li>
</ul>
<p>ActivityPub also specifies further properties for accessing additional streams; <code>following</code> and <code>followers</code> are expected, and the rest are optional:</p>
<ul>
<li><code>following</code>: An ActivityStreams 2.0 collection of the actors that this actor is following.</li>
<li><code>followers</code>: An ActivityStreams 2.0 collection of the actors that follow this actor
<li><code>liked</code>: An ActivityStreams 2.0 collection of every <code>object</code> from all of the actor's <code>Like</code> activities (generated automatically by the server).</li>
<li><code>streams</code>: A list of supplementary Collections which may be of interest. </li>
<li><code>preferredUsername</code></li>
<li><code>endpoints</code>: A mapping of additional (typically server/domain-wide) endpoints which may be useful either for this actor or someone referencing this actor:
<code>proxyUrl</code>, <code>oauthAuthorizationEndpoint</code>, <code>oauthTokenEndpoint</code>, <code>provideClientKey</code>, <code>signClientKey</code>, <code>sharedInbox</code>.</li>
<li>and any other applicable ActivityStreams 2.0 properties.</li>
</ul>
<p>[[Activitypub]] permits arbitrary collections to be created through specifying special behavior for the server when it receives activities with types <code>Add</code> and <code>Remove</code>. When a server receives such an activity in the <code>outbox</code>, and the <code>target</code> is a <code>Collection</code>, it adds the <code>object</code> to the <code>target</code> (for <code>Add</code>) or removes the <code>object</code> from the <code>target</code> (for <code>Remove</code>).</p>
</section>
<section id="inbox-interop">
<h4>Inboxes</h4>
<p>An Inbox is an endpoint to which new objects may be <a href="#delivery">delivered</a>. It also serves as a collection whose contents may be read. The Inbox endpoint is used by both ActivityPub and LDN, and can be discovered through the properties:
<ul>
<li><code>ldp:inbox</code> (<code>http://www.w3.org/ns/ldp#inbox</code>)</li>
<li><code>as:inbox</code> (<code>https://www.w3.org/ns/activitystreams#inbox</code>)</li>
</ul>
<p>In terms of JSON-LD, the latter is an alias of the former.</p>
<p>For how and when to <em>write</em> to an Inbox, see <a href="#delivery">delivery</a>.</p>
<p>The contents of this collection may also be read. While ActivityPub and LDN align for <em>writing</em> to an Inbox, due to irritating but ultimately unavoidable compatibility requirements with AS2 and LDP respectively, they use different vocabularies when Inbox contents are returned for <em>reading</em>. Fortunately for consuming clients to check for both vocabularies or for publishers to publish using both is not a huge implementation hurdle, so bridging is fairly trivial.</p>
<ul>
<li>ActivityPub Inboxes are an ActivityStreams 2.0 <code>OrderedCollection</code>, and link to their contents with the <code>items</code> property.</li>
<li>LDN Inboxes are an [[LDP]] <code>Container</code> (providing an explicit type is optional), and link to their contents with the <code>contains</code> property.</li>
</ul>
<p>In addition, ActivityPub has more constraints on the format of the JSON-LD returned. The two lists to follow describe how to bridge the small differences between ActivityPub and LDN conformant Inboxes.</p>
<p><strong>ActivityPub servers</strong> wishing to be read by LDN consumers:</p>
<ul>
<li>must return alongside the <code>items</code> for everything in the collection, an <code>ldp:contains</code> (<code>http://www.w3.org/ns/ldp#contains</code>) relation.</li>
</ul>
<p><strong>ActivityPub clients</strong> wishing to read from LDN Inboxes:</p>
<ul>
<li>must request content with the content-type <code>application/ld+json</code>. Running it through JSON-LD compaction should help to format the respone in a more friendly way.</li>
<li>must look for items in the Inbox via the <code>ldp:contains</code> property (rather than AS2 <code>items</code>).</li>
<li>should not expect any of the items to have their properties nested; will probably need to retrieve individual items from the URLs in the <code>@id</code> property.</li>
<li>Note the possibility of multiple vocabularies within the items in the Inbox themselves, including potentially a complete absence of any AS2.</li>
</ul>
<p><strong>LDN receivers</strong> wishing to be readable by ActivityPub consuming clients:</p>
<ul>
<li>must treat the content-type <code>application/activity+json</code> as equivalent to <code>application/ld+json; profile="http://www.w3.org/ns/activitystreams"</code>.</li>
<li>serve Inbox contents as an AS2 <code>Collection</code>, where each notification is related to the inbox with the AS2 <code>items</code> property.</li>
<li>must return compacted JSON-LD, and no <code>@graph</code>, serving the Inbox collection as the root of the document.</li>
<li>may make life easier by nesting additional properties of each resource in the Inbox.</li>
</ul>
<p><strong>LDN consumers</strong> wishing to read from Inboxes on ActivityPub servers:</p>
<ul>
<li>must, if content is returned with the content-type <code>application/activity+json</code> and missing an <code>@context</code>, apply the default AS2 context, and treat it as JSON-LD.</li>
<li>must look for items in the Inbox via the AS2 <code>items</code> property (rather than <code>ldp:contains</code>).</li>
</ul>
</section>
</section>
</section>
<section id="publishing">
<h2>Publishing</h2>
<p>Publishing in this context refers to modifying the outgoing feed associated with a particular profile. This incorporates creating new content, as well as updating or deleting existing content. Content generated through a client (such as a web form, mobile app, sensor, smart device) is created when it is sent to a server for processing, where it is typically stored and usually published (either publicly or to a restricted audience), in human- and/or machine-readable forms. Clients and servers may independently support creating, updating and deleting; there are no dependencies between them.</p>
<p class="note" title="Other kinds of publishing">
While delivering notifications or responding to subscription requests may trigger creating (or updating or deleting) something on the receiving end, the intent is different. These cases are called out as side effects in subscription and delivery where appropriate.
</p>
<p>For notes about authentication and authorization between clients and servers, see <a href="#auth"></a></p>
<p>The two specifications recommended by the Social Web Working Group for publishing are [[Activitypub]] and [[Micropub]]. They use similar high level mechanisms, but differ in requirements around both the vocabularies and content types of data. </p>
<p>ActivityPub contains a client-to-server API for creating ActivityStreams 2.0 objects and activities, and specifies additional responsibilities for clients around addressing objects, and for servers around the side-effects of certain types of objects. </p>
<p>Micropub provides a basic client-to-server API for creating blog-post-type content and is intended as a quickstart for content creation, on top of which more complex (but optional) actions can be layered. Micropub also provides a media endpoint for uploading files.</p>
<div class="note" title="REST">
<p>Neither ActivityPub nor Micropub define APIs for publishing based on HTTP verbs. If you're looking for something more RESTful, you may like the Linked Data Platform [[LDP]].</p>
</div>
<section id="creating">
<h3>Creating</h3>
<p>The publishing endpoint of <strong>[[Activitypub]]</strong> is the <code>outbox</code>. Clients are assumed to have the URL of a (ideally authenticated) profile as a starting point, and discover the value of the <code>https://www.w3.org/ns/activitystreams#outbox</code> property found at the profile URL (which should be available as JSON). The client then makes an HTTP <code>POST</code> request with an ActivityStreams 2.0 activity or object as a JSON payload with a content type of <code>application/ld+json; profile="https://www.w3.org/ns/activitystreams"</code>. The URL of the created resource is generated at the discretion of the server, and returned in the <code>Location</code> HTTP header. This is an appropriate protocol to use when:</p>
<ul>
<li>You want to send/receive a JSON or JSON-LD payload.</li>
<li>Your data is described with [[activitystreams-core]] and [[activitystreams-vocabulary]] (optionally extensible via JSON-LD).</li>
<li>You want servers to carry out a known set of actions upon content creation.</li>
</ul>
<p>Side-effects of creating content with ActivityPub are for the most part adding things to various different collections collections (likes, follows, etc); but also include requirements about blocking users, and a hook to enable federated servers.</p>
<p>The publishing endpoint for <strong>[[Micropub]]</strong> is the <code>micropub</code> endpoint. Clients discover this from a profile URL via a <code>rel="micropub"</code> link (in an HTTP <code>Link</code> header, or an HTML <code><link></code> element). Clients make a <code>x-www-form-urlencoded</code> POST request containing the key-value pairs for the attributes of the object being created. The URL of the created resource is generated at the discretion of the server, and returned in the <code>Location</code> HTTP header. Clients and servers must support attributes from the Microformats2 [[h-entry]] vocabulary. Micropub also defines four reserved attributes (<code>access_token</code>, <code>h</code>, <code>action</code> and <code>url</code>) as well as reserves any attribute prefixed with <code>mp-</code>; these are used as commands to the server. Any additional key names sent outside of these vocabularies <em>may</em> be ignored by the server.</p>
<p>Micropub requests may alternatively be sent as a JSON payload, the syntax of which is derived from [[microformats2-parsing]].</p>
<p>This is an appropriate protocol to use when:</p>
<ul>
<li>You want to send/receive a form-encoded or JSON payload.</li>
<li>Your data is described with the [[h-entry]] syntax and vocabulary.</li>
<li>You can rely on out-of-band agreements between clients and servers for vocabulary extensibility.</li>
</ul>
</section>
<section id="updating">
<h3>Updating</h3>
<p>Content is updated when a client sends changes to attributes (additions, removals, replacements) to an existing object.</p>
<p><strong>[[Activitypub]]</strong> clients send an HTTP <code>POST</code> request to the <code>outbox</code> containing an ActivityStreams 2.0 <code>Update</code> activity. The <code>object</code> of the activity is an existing object, including its <code>id</code>, and the fields to update should be nested. If a partial representation of an object is sent, omitted fields are <em>not</em> deleted by the server. In order to delete specific fields, the client can assign them a <code>null</code> value. </p>
<p>In the case of ActivityPub federated servers, updates should be propagated to the <code>inbox</code>es of recipients of the original objects. However, when a federated server passes an <code>Update</code> activity to another server's <em><code>inbox</code></em>, the recipient must assume this is the <em>complete</em> object to be replaced; partial updates are not performed server-to-server.</p>
<p>An <code>Undo</code> with the <code>object</code> of the previous <code>Update</code> can be used to revert changes.</p>
<p><strong>[[Micropub]]</strong> clients perform updates as JSON POST requests, using the <code>"action": "update"</code> directive, as well as a <code>replace</code>, <code>add</code> or <code>delete</code> property containing the updates to make, to the Micropub endpoint. <code>replace</code> replaces all values of the specified property; if the property does not exist already, it is created. <code>add</code> adds new values to the specified property without changing the existing ones; if the property does not exist already, it is created. <code>delete</code> removes the specified property; you can also remove properties by value by specifying the value.</p>
<p>If a server also implements [[Webmention]] it should propagate the updates to anyone who received Webmentions for the original.</p>
<p>If a server also implements [[WebSub]], and the updated resource is part of a <code>topic</code>, the server should notify the hub of an update to the topic URL.</p>
</section>
<section id="deleting">
<h3>Deleting</h3>
<p>Content is deleted when a client sends a request to delete an existing object.</p>
<p><strong>[[Activitypub]]</strong> clients delete an object by sending an HTTP POST request containing an ActivityStreams 2.0 <code>Delete</code> activity to the <code>outbox</code> of the authenticated user. Servers must either <em>replace</em> the <code>object</code> of this activity with a tombstone and return a <code>410 Gone</code> status code, or return a <code>404 Not Found</code>, from its URL.</p>
<p>An <code>Undo</code> with the <code>object</code> of the previous <code>Delete</code> may be used to restore the object.</p>
<p><strong>[[Micropub]]</strong> delete requests are two key-value pairs, JSON: <code>"action": "delete"</code> and <code>"url": url-to-be-deleted</code>, sent to the Micropub endpoint. Posts may be resotred with <code>"action": "undelete"</code>.</p>
<p>As with <a href="#updating">updating</a>, servers implementing ActivityPub federation, Webmention or WebSub should propagate deletes accordingly.</p>
</section>
</section>
<section id="subscribing">
<h2>Subscribing</h2>
<p>An agent (client or server) may <em>ask</em> to be notified of changes to a content object (eg. edits, new replies) or stream of content (eg. objects added or removed from a particular stream). This is <em>subscribing</em>. Specifications which contain subscription mechanisms are ActivityPub and WebSub.</p>
<p class="note" title="Subscription vs delivery">Receiving notifications does not need to rely on implementation of a subscription mechanism. That is, implementations may set themselves up to receive notifications without always being required to explicitly ask for them from a sender or publisher: see <a href="#delivery">delivery</a>.</p>
<section id="subscribing-with-follow">
<h3>Subscribing with <code>as:Follow</code></h3>
<p><strong>[[Activitypub]]</strong> servers maintain a <em>Followers</em> collection for all users. This collection may be directly addressed, or addressed automatically or by default, in the <code>to</code>, <code>cc</code> or <code>bcc</code> field of any Activity. As a result, federated servers <a href="#delivery">deliver</a> the Activity to the <code>inbox</code> of each profile in the collection.</p>
<p>Subscription requests are essentially requests to be added to this collection. They are made by the subscriber's server <code>POST</code>ing a <code>Follow</code> Activity to the target's <code>inbox</code>. This request should be authenticated, and therefore doesn't need additional verification. The target server then should add the subscriber to the target's Followers collection. Exceptions may be made if, for example, the target has blocked the subscriber.</p>
<p>This is a suitable subscription mechanism when:</p>
<ul>
<li>The subscriber wants to request updates from a specific profile's <code>outbox</code> (rather than objects, streams, feeds, collections, conversation threads).</li>
<li>The subscriber and publisher both speak ActivityStreams 2.0.</li>
<li>The publisher is aware of who has subscribed, and capable of delivering content to subscribers itself.</li>
</ul>
<p>Since delivery is only a requirement for federated servers, prospective subscribers will not be able to <code>POST</code> their <code>Follow</code> activity to the <code>inbox</code> of a profile which is on a non-federated server (expect a <code>405 Method Not Allowed</code>), and thus are not able to subscribe to these profiles. In this case, prospective subscribers may wish to periodically <em>pull</em> from the publisher's <code>outbox</code> instead.</p>
</section>
<section id="subscribing-hub">
<h3>Subscribing with a hub</h3>
<p><strong>[[WebSub]]</strong> provides a mechanism to delegate subscription handling and delivery of content to subscribers to a third-party, called a <em>hub</em>. All publishers need to do is link to their chosen hub(s) using HTTP <code>Link</code> headers or HTML <code><link> </code> elements with <code>rel="hub"</code>, and then notify the hub when new content is available. The mechanism for notifying the hub is left deliberately unspecified, as publishers may have their own built in hub, and therefore use an internal mechanism.</p>
<div class="note" title="Notifying the hub">
<p>A mechanism for communcation between publishers and hubs may be standardised in future as an extension.</p>
</div>
<p>The subscriber discovers the hub from the publisher, and sends a form-encoded <code>POST</code> request containing values for <code>hub.mode</code> ("subscribe"), <code>hub.topic</code> (the URL to subscribe to) and <code>hub.callback</code> (the URL where updates should be sent to, which should be 'unguessable' and unique per subscription). The hub and subscriber carry out a series of exchanges to verify this request.</p>
<p>When the hub is notified of new content by the publisher, the hub fetches the content of the <code>topic</code> URL, and sends this to the subscriber's <code>callback</code> URL via a POST request. The body of the request is the content of the topic URL, and the <code>Content-Type</code> must match. A <code>rel=hub</code> <code>Link</code> header should be included.</p>
<p>This is a suitable subscription mechanism when:</p>
<ul>
<li>The subscriber wants to request updates from any resource (not just user profiles), and of any content type.</li>
<li>Subscription requests are not authenticated, so you need a way to verify them.</li>
<li>The publisher wants to delegate distribution of updates to another service (the hub) instead of doing it itself.</li>
</ul>
<div class="note" title="WebSub and LDN">
<p>LDN Receivers can be used to receive deliveries from WebSub hubs by using the <code>inbox</code> URL as the <code>hub.callback</code> URL and <em>either</em> only subscribing to resources published as JSON-LD <em>or</em> accepting content-types other than JSON-LD.</p>
</div>
</section>
</section>
<section id="delivery">
<h2>Delivery</h2>
<p>A user or application may wish to push a notification to another user that the receiver has <em>not explicitly asked</em> for. For example to send a message or some new information; because they have linked to (replied, liked, bookmarked, reposted, etc) their content; because they have linked to (tagged, addressed) the user directly; to make the recipient aware of a change in state of some document or resource on the Web. The Social Web Working Group specifications contain several mechanisms for carrying out delivery; they are listed here from general to specialised.</p>
<p class="note" title="Delivery vs subscription">We need to leave it open for users to refuse content they have <em>not</em> explicitly <a href="#subscribing">subscribed</a> to, ie. nothing else should rely on implementation of delivery.</p>
<section id="targeting-and-discovery">
<h3>Targeting and discovery</h3>
<p>The target of a notification is usually the addressee or the subject, as referenced by a URL. The target may also a resource which has previously requested notifications through a <a href="#subscribing">subscription</a> request. Once you have determined your target, you need to discover where to send the notification for that particular target. Discovery is fetching the target URL and looking for a link to an endpoint which will accept the type of notification you want to send (read on, for all of your exciting options).</p>
<p>Bear in mind that many potential targets will <em>not</em> be configured to receive notifications at all. To avoid overloading unsuspecting servers with discovery-related requests, your application should employ a "back-off" strategy when carrying out discovery multiple times to targets on the same domin. This could involve increasing the period of time between subsequent requests, or caching unsuccessful discovery attempts so those domains can be avoided in future. You may wish to send a <code>User-Agent</code> header with a reference to the notification mechanism you are using so that recipient servers can find out more about the purpose of your requests.</p>
<p>Your application should also respect relevant cache control and retry headers returned by the target server.</p>
</section>
<section id="delivery-generic">
<h3>Generic notifications</h3>
<p><strong>[[LDN]]</strong> is a federation protocol for sending, receiving and consuming notifications which may contain any content, and be triggered by any person or process. Senders, receivers and consumers can all be on different domains. This is a suitable notification mechanism when:</p>
<ul>
<li>Notifications need to be identifiable with their own URLs and exposed by the receiver for other applications to discover and re-use.</li>
<li>Notifications are represented as a JSON-LD payload (ie. a 'fat ping').</li>
<li>You need to advertise constraints on the type or contents of notifications accepted by a receiver.</li>
</ul>
<p>[[LDN]] functionality is divided between <em>senders</em>, <em>receivers</em> and <em>consumers</em>. The endpoint to which notifications are sent is the <code>inbox</code>. Any resource (a user profile, blog post, document) can advertise its <code>inbox</code> so that it may be discovered through an HTTP <code>Link</code> header or the document body in any RDF syntax (including JSON-LD or HTML+RDFa). To this Inbox, senders make a <code>POST</code> request containing the JSON-LD (or other RDF syntax per [[Accept-Post]] negotation with the receiver) payload of the notification. The receiver returns a URL from which the notification data can be retrieved, and also adds this URL to a list which is returned upon a <code>GET</code> request to the Inbox (see <a href="#reading"></a>). Consumers can retrieve this Inbox listing, and from there the individual notifications, as JSON-LD (optionally content negotiated to another RDF syntax). An obvious type of consumer is a script which displays notifications in a human-readable way.</p>
<div class="note" title="LDP compatibility">
<p>An existing [[LDP]] implementation can serve as an [[LDN]] receiver out of the box; publishers simply advertise any <code>ldp:Container</code> as the <code>inbox</code> for a resource.</p>
</div>
<p>The payload of notifications is deliberately left open so that LDN may be used in a wide variety of use cases. However, receivers with particular purposes are likely to want to constrain the types of notifications they accept. They can do this transparently (such that senders are able to attempt to conform, rather than having their requests rejected opaquely) by advertising data shapes constraints such as [[SHACL]]. Advertisement of such constraints also allows consumers to understand the types of notifications in the Inbox before attempting to retrieve them. Receivers may reject notifications on the basis of internal, undisclosed constraints, and may also access control the Inbox for example by requiring an <code>Authorization</code> header from both senders and consumers.</p>
<p><strong>[[WebSub]]</strong> <em>publishers</em> deliver content to their <em>hub</em>, and <em>hubs</em> to their <em>subscribers</em> using HTTP <code>POST</code> requests. The body of the request is left to the discretion of the sender in the first case, and in the latter case must match the Content-Type of and contain contents from the <code>topic</code> URL.</p>
</section>
<section id="delivery-activities">
<h3>Activity notifications</h3>
<p><strong>[[Activitypub]]</strong> uses [[LDN]] to send notifications with some specific constraints. These are:</p>
<ul>
<li>The notification payload MUST be a single ActivityStreams 2.0 Activity.</li>
<li>The notification payload MUST be compact JSON-LD.</li>
<li>The receiver MUST verify the notification by fetching its source from the origin server.</li>
<li>All notification <code>POST</code> requests are authenticated.</li>
</ul>
<p>[[Activitypub]] specifies how to define the <em>target(s)</em> to which a notification is to be sent (a pre-requisite to [[LDN]] sending), via the [[activitystreams-vocabulary]] audience targeting and object linking properties.</p>
<p>[[Activitypub]] also defines side-effects that must be carried out by the server as a result of notification receipt. These include:</p>
<ul>
<li>Creating, updating or deleting new objects upon receipt of <code>Create</code>, <code>Update</code> and <code>Delete</code> activities.</li>
<li>Reversing the side-effects of prior activities upon receipt of the <code>Undo</code> activity.</li>
<li>Updating specialised collections for <code>Follow</code>, <code>Like</code> and <code>Block</code> activities.</li>
<li>Updating any other collections upon receipt of <code>Add</code> and <code>Remove</code> activities.</li>
<li>Carrying out further delivery to propagate activities through the network in the case of federated servers.</li>
</ul>
<div class="note" title="The inbox property">
<p>ActivityPub actor profiles are linked to their inboxes via the <code>https://www.w3.org/ns/activitystreams#inbox</code> property. This is an <em>alias</em> (in the AS2 JSON-LD context) for LDN's <code>http://www.w3.org/ns/ldp#inbox</code>. Applications using a full JSON-LD processor to parse these documents will see these terms as one and the same. Applications doing naive string matching on terms may wish to note that if you find an <code>ldp:inbox</code> it will accept <code>POST</code> requests in the same way as an <code>as:inbox</code>.</p>
</div>
</section>
<section id="delivery-mentioning">
<h3>Mentioning</h3>
<p><strong>[[Webmention]]</strong> provides an API for sending and receiving notifications when a relationship is created (or updated, or deleted) between two documents. A webmention sender is triggered by the creation (or modification) of content which includes the URL of another document. It works when the two documents are on different domains, thus serving as a federation protocol. This is a suitable notification mechanism when:</p>
<ul>
<li>You have a document (source) which contains the URL of another document (target).</li>
<li>The owner of the endpoint has access to view the source (so the request can be verified).</li>
<li>The only data you need to send over the wire are the URLs of the source and target documents (ie. a 'thin ping').</li>
</ul>
<p>There are no constraints on the syntax of the source and target documents. Discovery of the [[Webmention]] endpoint (a script which can process incoming webmentions) is through a link relation (<code>rel="webmention"</code>), either in the HTTP <code>Link</code> header or HTML body of the target. This endpoint does not need to be on the same domain as the target, so webmention receiving can be delegated to a third party.</p>
<p>Webmentions are verified by the server dereferencing the source and parsing it to check for the existence of the target URL. If the target URL isn't found, the webmention MUST be rejected.</p>
<p>Webmention uses <code>x-www-form-urlencoded</code> for the source and target as parameters in an HTTP POST request. Beyond verification, it is not specified what the receiver should do upon receipt of a Webmention. What the webmention endpoint should return on a <code>GET</code> request is also left unspecified.</p>
<section id="webmention-updates">
<h4>Updates and deletes</h4>
<p>In practice, Webmention receivers tend to fetch and store the webmention source. It is often displayed, for example as a reply underneath the target blog post.</p>
<p>If a Webmention is received and this is the first time this <code>source</code> and <code>target</code> combination has been seen by the receiver, this indicates a relationship between the <code>source</code> and <code>target</code> has been created. If the receiver has seen these values before, the receiver can fetch and parse the <code>source</code> to determine what has changed; either the content of the <code>source</code> has been updated (in which case the receiver can update local copies of the content, if it stored them in the first place), or the entire source has been deleted (expect a <code>410 Gone</code> response).</p>
</section>
</section>
<section id="delivery-interop">
<h3>Delivery interop</h3>
<p>This section describes how implementations of Webmention, ActivityPub and LDN may create bridging code in order to send and receive notifications from the others.</p>
<section id="wm-as-as">
<h4>Webmention as AS2 / ActivityPub</h4>
<p>A webmention may be represented as a persistent resource with the ActivityStreams 2.0 vocabulary. This could come in handy if a <strong>Webmention sender</strong> <em>mentions</em> a user known to be running an ActivityPub federated server, and wants a generic (ie. not ActivityPub specific) way of notifying about this. In this case, the sender can use an AS2 payload and deliver the notification per <a href="#wm-to-ldn"></a>.</p>
<pre class="example" id="wm-as2">
{
"@context": "https://www.w3.org/ns/activitystreams#",
"type": "Relationship",
"subject": "https://waterpigs.example/post-by-barnaby",
"object": "https://aaronpk.example/post-by-aaron"
}
</pre>
<p>A receiver or sender may want to augment this representation with the relationship between the two documents, and any other pertinent data. In the receiver's case, this could be gathered when they parse the source during the verification process. For example:</p>
<pre class="example">
{
"@context": "https://www.w3.org/ns/activitystreams#",
"type": "Relationship",
"subject": {
"id": "https://waterpigs.example/post-by-barnaby",
"name": "Hi Aaron, great post."
},
"object": {
"id": "https://aaronpk.example/post-by-aaron",
"name": "Aaron's first post."
},
"relationship": "inReplyTo"
}
</pre>
</section>
<section id="ldn-to-wm">
<h4>LDN to Webmention</h4>
<p><strong>Webmention receivers</strong> wishing to also accept LDN <code>POST</code>s at their Webmention endpoint must:</p>
<ul>
<li>Advertise the webmention endpoint via <code>rel="http://www.w3.org/ns/ldp#inbox"</code> in addition to <code>rel="webmention"</code> (in the <code>Link</code> header, HTML body or JSON body of a target).</li>
<li>Accept <code>POST</code> requests with the Content-Type <code>application/ld+json</code>. Expect the body of the request to be:
<pre class="example">
{
"@context": "http://www.w3.org/ns/webmention#",
"@id": "",
"source": { "@id": "https://waterpigs.example/post-by-barnaby" },
"target": { "@id": "https://aaronpk.example/post-by-aaron" }
}
</pre>
Use the <code>source->@id</code> and <code>target->@id</code> values as the <code>source</code> and <code>target</code> of the Webmention, and proceed with verification.</li>
<li>If returning a <code>201 Created</code>, it MUST return a <code>Location</code> header with a URL from which the contents of the request posted can be retrieved. <code>202 Accepted</code> is still fine.</li>
<li>Note than when verifying the source, there's a good chance you can request/parse it as RDF.</li>
</ul>
<p><strong>LDN senders</strong> wishing to send to Webmention endpoints basically just need to implement Webmention sending. The Webmention endpoint is at <code>rel="webmention"</code> (either in an HTTP <code>Link</code> header or HTML <code><link></code> element).</p>
<p>Note that Webmention endpoints will only verify a received notification if the <code>source</code> is publicly retrievable and contains the URL of the <code>target</code>.</p>
</section>
<section id="wm-to-ldn">
<h4>Webmention to LDN</h4>
<p><strong>LDN receivers</strong> wishing to also accept Webmentions to their Inbox MUST:</p>
<ul>
<li>Advertise the Inbox via <code>rel="webmention"</code> in addition to <code>rel="http://www.w3.org/ns/ldp#inbox"</code> (in the <code>Link</code> header, HTML body or JSON body of a target).</li>
<li>Accept <code>POST</code> requests with a content type <code>application/x-www-form-urlencoded</code>. Convert these requests from:
<pre class="example">
source=https://waterpigs.example/post-by-barnaby&
target=https://aaronpk.example/post-by-aaron
</pre>
to:
<pre class="example" id="wm-json">
{
"@context": "http://www.w3.org/ns/webmention#",
"@id": "",
"source": { "@id": "https://waterpigs.example/post-by-barnaby" },
"target": { "@id": "https://aaronpk.example/post-by-aaron" }
}
</pre>
and proceed per [[LDN]]; receivers MAY add other triples at their discretion.</li>
<li>Receivers MUST return a <code>201 Created</code> with a <code>Location</code> header or <code>202 Accepted</code>.</li>
<li>Receivers MUST verify the request by retrieving the source document and checking a link to the target document is present. If the Webmention is not verified, recievers MUST NOT keep it.</li>
</ul>
<p><strong>Webmention senders</strong> wishing to send to LDN Inboxes need to send a JSON-LD payload. Discover the Inbox endpoint through a relation of <code>http://www.w3.org/ns/ldp#inbox</code> between the <code>target</code> and the Inbox. A typical Webmention can be represented as JSON-LD per <a href="#wm-json">this example</a>, or as ActivityStreams 2.0 JSON per <a href="#wm-as2">this example</a>.</p>
</section>
<p class="note" title="Bridging services">
Look out for Webmention-ActivityPub bridges <em>as services</em>. These will provide endpoints to do the heavy lifting of the spec you don't want to implement yourself. You can use these endpoints as your Webmention or Inbox endpoint respectively. Brainstorming and implementations of such bridges can be found on the <a href="https://www.w3.org/wiki/SocialCG">Social Web Community Group</a> and the <a href="https://indieweb.org/bridge#ActivityPub">IndieWeb community</a>.
</p>
</section>
</section>
</section>
<section id="profiles">
<h2>Profiles</h2>
<p>The subject of a profile document can be a person, persona, organisation, bot, location, or other. None of the specifications described here prescribe particular relationships between real-world entities and online profiles. That is, one person can have many profiles, and one profile may be controlled by many people. How/if/when multiple profiles are linked together is implementation specific, and not specified anywhere here.</p>
<p>Most specifications expect that profiles are identified by and retrieved from a URL, and that attributes of the subject of the profile are available from the URL. Ideally they also return a link to at least one stream of content associated with the profile (or embed the content directly), for example activities or blog posts.</p>
<p><strong>ActivityPub</strong> profiles are JSON-LD documents containing any appropriate ActivityStreams 2.0 properties, as well as links to various endpoints and collections (see <a href="#streams-special"></a>).</p>
<p><strong>ActivityStreams 2.0</strong> has various <a href="https://www.w3.org/TR/activitystreams-core/#actors">Actor types</a>, which may be used to represent individuals or groups, and also includes <code>Profile</code>.</p>
<p><strong>Micropub</strong> has a notion of a profile page (URL) that represents a user, but does not specify the format of that page, except for the link to the Micropub endpoint and authorization endpoints for clients to discover.</p>
<p><strong>Webmention</strong> does not specify any particular profile format, but in practice Webmention implementations typically publish and consume [[h-card]] profile information to display authors of webmention sources (see <a href="https://www.w3.org/TR/webmention/#webmention-verification-p-4">examples in the Webmention spec</a>).</p>
<section id="relationships">
<h3>Relationships</h3>
<p>Semantics and representation of personal relationships are implementation specific. These specifications deal with relationships only when distribution of content is affected, for example when 'following' triggers a subscription request from one server to another. Lists of other relationships may be discoverable from a user profile, should be represented according to the ActivityStreams 2.0 syntax and may (and are likely to) use extension vocabularies as needed.</p>
<ul>
<li><strong>ActivityPub:</strong> When a server receives a <code>Follow</code> Activity in its <code>inbox</code>, the subject is added to a <code>Followers</code> <code>Collection</code>, which is discoverable from the subject's profile. Federated servers use this collection to deliver updates when new content is created by the owner of the collection.</li>
</ul>
</section>
<section id="auth">
<h3>Authentication, authorization, and access control</h3>
<p>Authentication and authorization mechanisms were out of scope for the Social Web WG. Please follow the <a href="https://www.w3.org/wiki/SocialCG">Community Group</a> for development in this space. Meanwhile, some of the WG specifications contain non-normative notes on the topic:</p>
<ul>
<li><strong>ActivityPub:</strong> Points to a Community Group best practices report in <a href="https://www.w3.org/TR/activitypub/#authorization">B.1 Authentication and Authorization</a>.</li>
<li><strong>LDN:</strong> Recommends that receivers employ some kind of verification mechanism which <em>may</em> be authentication in <a href="https://www.w3.org/TR/ldn/#sender-verification">3.3.3 Sender verification</a>, with additional security considerations in <a href="https://www.w3.org/TR/ldn/#authenticated-inboxes">5.6 Authenticated inboxes</a>.</li>
<li><strong>Micropub:</strong> Requires bearer tokens, and suggests IndieAuth in <a href="https://www.w3.org/TR/micropub/#authentication-and-authorization">5. Authentication and Authorization</a>.</li>
<li><strong>Webmention:</strong> Points to an extension for use with access controlled posts in <a href="https://www.w3.org/TR/webmention/#private-webmention">B.3 Private Webmention</a>.</li>
<li><strong>WebSub:</strong> Describes optional use of HMAC Signatures in <a href="https://www.w3.org/TR/websub/#authenticated-content-distribution">8.1 Authenticated Content Distribution</a>.</li>
</ul>
</section>
</section>
<section id="related-specs">
<h2>Related specifcations</h2>
<p>Other specifications worth mentioning in relation to the output of the Social Web Working Group are outlined here.</p>
<p>Social Web Working Group Notes:</p>
<ul>
<li><strong>[[IndieAuth]]</strong>: is an identity layer on top of OAuth 2, and the expected auth mechanism for Micropub clients.</li>
<li><strong>[[JF2]]</strong>: is an alternative JSON syntax for social content, derived from[[microformats2]]. It includes individual objects and feeds. If you don't like ActivityStreams 2.0, you might like this instead. At the time of writing it is not referenced by any other Social Web Working Group specifications.</li>
<li><strong>[[post-type-discovery]]</strong>: specifies an algorithm for determining the type of post by its properties. This may help with bridging between content marked up with [[microformats2]], and explicitly typed vocabularies like ActivityStreams 2.0.</li>
</ul>
<p>External:</p>
<ul>
<li><strong>[[LDP]]</strong>: was an input to the Social Web Working Group charter. <code>Container</code>s on LDP servers can be used directly as LDN receivers, if you happen to have one lying around. The Web Annotation Protocol is also based on LDP.</li>
<li><strong>[[microformats2]]</strong>: is a way to mark up structured information in HTML. Micropub expects the microformats2 vocabulary, and Webmention receiver implementations often look for microformats2 markup to fetch more information about a source.</li>
<li><strong>[[annotation-protocol]]</strong>: uses ActivityStreams 2.0 Collections and Paging to model sets of annotations. Annotations themselves use the [[annotation-vocab]].</li>
</ul>
<p>Development of related specifications is ongoing in various communities, notably the <a href="https://www.w3.org/wiki/SocialCG">Social Web Community Group</a> and the <a href="https://indieweb.org">IndieWeb</a> community.</p>
</section>
<section id="change-log" class="appendix information">
<h2>Change Log</h2>
<section id="changes-since-2017-05-04">
<h3>Changes from 4 May 2017 WD to this version</h3>
<ul>
<li>Editorial updates throughout.</li>
<li>Update all spec functionality which had fallen behind (mostly Micropub).</li>
<li>Add requirements definitions to clarify the sections each spec is listed under, and their relation to charter deliverables.</li>
<li>Clarify relevence of Federation Protocols to Social API parts (ie. updates triggering new notifications etc).</li>
<li>Elaborate on Updates and Deletes for AP and Webmention.</li>
<li>Profiles now describes each spec's use or expectations of profiles.</li>
<li>Auth section now links to relevent parts of each individual spec.</li>