Copyright © 2016 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
The ActivityPub protocol is a social networking protocol based upon the ActivityStreams 2.0 data format. It is based upon experience gained from implementing and working with the OStatus and Pump.io protocols.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document is a proposed submission to the W3C Social working group
This document was published by the Social Web Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-socialweb@w3.org (subscribe, archives). All comments are welcome.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 September 2015 W3C Process Document.
The ActivityPub protocol is broadly based on the distribution of activities, described using [ActivityStreams]; these activities are produced in response to a user performing an activity. Most activities are purely responsive in nature - they are produced as a response to a user having done something. In addition, certain activities posted by a user to their outbox may trigger certain operations on the user's behalf. Finally, activities may have side effects as they propogate throughout the social graph. As an example of this:
like
activity to their outbox. This
activity causes the user's server to perform an activity on behalf of
the user; in particular, it adds the specified object to the collection
of objects the user has liked.This specification defines two closely related and interacting protocols:
All servers claiming conformance to this specification are required to implement the former protocol, and may optionally implement the latter. This gives three conformance classes:
It is called out whenever a portion of the specification only applies to implementation of the federation protocol. In addition, whenever requirements are specified, it is called out whether they apply to the client or server (for the client-to-server protocol) or which of a pair of servers in the server-to-server protocol.
Objects are the core concept around which both [ActivityStreams] and ActivityPub are built. Objects are often wrapped in Activities and are contained in streams of Collections, which are themselves subclasses of Objects. See the ActivityStreams Vocabulary document, particularly the Core Classes, to get a sense of how this lays out; ActivityPub follows the mapping of this vocabulary very closely.
Servers SHOULD validate the content they receive to avoid content spoofing attacks. In particular, servers SHOULD NOT trust client submitted content, and federated servers also SHOULD NOT trust content received from a server other than the content's origin without some form of verification. The general mecahism that is specified for this at this time is for a recipient of some referenced activitystreams object to verify the presence of that object on the original server. Other mechanisms such as verifying signatures are left out of scope of this document. (However, if other generally agreed upon mechanisms for handling verification become available in the future, servers are welcome to use those methods, in the future.)
{ "@context": "http://www.w3.org/ns/activitystreams", "@type": "Like", "actor": "https://example.net/~mallory", "object": { "@id": "https://example.org/~alice/note/23", "author": "https://example.org/~alice", "content": "I'm a goat" } }
id
both to ensure that it exists
and is a valid object, and that it is not misrepresenting the object.
(In this example, Mallory could be spoofing an object allegedly posted by Alice.)
All Objects in [ActivityStreams] should have unique global identifiers. ActivityPub extends this requirement; all objects distributed by the ActivityPub protocol MUST have unique global identifiers; these identifiers must fall into one of the following groups:
null
object, which
implies an anonymous object (a part of its parent context)A server receiving an object with no specified id
should
allocate an object ID in the user's namespace and attach it to the posted
object.
All objects must have the following properties:
There are several common operations upon social objects, which are expressed using standard HTTP methods applied to the Object's dereferencable URI. To avoid conflict with existing standards (and hence support "multiprotocol" server implemnetations), the scope of requests which servers are required to honor as defined in this specification is limited as follows:
DELETE
method will
always be honored as specified in 3.2.3 The DELETE methodapplication/activity+json
, or where explicitly
permitted the multipart/related
media type with a root part
of type application/activity+json
Accept
header MUST be
specified, and the behavior defined by this specification ONLY applies
if content negotion results in the selection of the
application/activity+json
media type. For requests
with a body, the client MAY omit the Accept
header, in
which case the server MUST provide successful responses as defined by this
specificationServers MAY implement other behavior for requests which do not comply with the above requirements. (For example, servers may implement additional legacy protocols, or may use the same URI for both HTML and ActivityStreams representations of a resource)
Servers MAY require authorization as specified in 5. Authorization, and may additionally implement their own authentication rules. Servers SHOULD fail requests which do not pass their authorization or authentication checks with the appropriate HTTP error code, or the 404 Not Found error code where the existence of the object is considered private.
GET
methodThe GET method shall return an up-to-date version of the object.
PUT
methodThis method requires user authorization
The PUT method may be used by a client to update the version of the object stored on the server.
The server MUST insert an activity with the @type
Update
and this object as its object
into the actor's
feed.
DELETE
methodThis method requires user authorization
The DELETE
method may be used by a client to delete the
object. If successful, all requests to the URI which would have
previously been successful SHOULD return the 410 Gone response code.
Actors in ActivityPub are represented by HTTP URI. When entered directly into a user interface (for example on a login form), it is desirable to support simplified naming. For this purpose cases, ID normalization SHOULD be performed as follows:
Once the actor's URI has been identified, it should be dereferenced.
Actor objects are ActivityStreams objects which are subclasses of the
actor
type. Actor objects MUST have, in addition to the
properties mandated by 3.1 Object Identifiers, the following properties:
id
Implementations should, in addition, provide the following properties:
{ "@context": [ "http://www.w3.org/ns/activitystreams", "http://www.w3.org/ns/activitypub" ], "@type": "Person", "@id": "https://johnsmith.example.com/", "following": "https://johnsmith.example.com/following.json", "followers": "https://johnsmith.example.com/followers.json", "inbox": "https://johnsmith.example.com/inbox.json", "outbox": "https://johnsmith.example.com/feed.json", "preferredUsername": "johnsmith", "name": "John Smith", "summary": "Just an example guy", "icon": [ "https://johnsmith.example.com/image/165987aklre4" ] }
When a user dereferences an actor's ID the page MUST contain HTML script
element with the type
attribute set to
application/ld+json
.
<script type="application/ld+json"> { "@context": [ "http://www.w3.org/ns/activitystreams", "http://www.w3.org/ns/activitypub" ], "@id": "https://example.com/~alice/my-stream", "@type": "Person", "name": "Alice", "summary": "Hai, I'm Alice!", "inbox": "https://example.com/~alice/inbox", "outbox": "https://example.com/~alice/feed", "followers": "https://example.com/~alice/collections/followers", "following": "https://example.com/~alice/collections/following" } </script>
[ActivityStreams] defines the collection concept; ActivityPub defines several collections with special behavior. Additionally, it defines a subset of collections termed streams.
Every actor MUST have a followers collection. This is the default recipient list for otherwise unaddressed activities, and additionally is used as a distribution target for any activities addressed to the public.
Every actor MAY have a following collection. This is a list of everybody that the actor has followed
Every actor MAY have a likes collection. This is a list of every object that the actor has marked as having liked. (See the Like activity.)
The streams nomencluture is applied to any collection comprosed purely of
activities. These objects should be so declared using the objectTypes
property:
{ "@context": [ "http://www.w3.org/ns/activitystreams", "http://www.w3.org/ns/activitypub" ], "@id": "https://example.com/~alice/my-stream", "@type": "Collection", "itemsType": ["activity"] "items": [ ... ] }
Streams are always presented in reverse chronological order
The outbox
stream contains objects the user
has published, subject to the ability of the requestor to retrieve
the object (That is, the contents of the outbox are filtered by the
permissions of the person reading it). If a user submits a request
without Authorization the server should
respond with all of the Public posts.
This could potentially be all relevant objects published by
the user, though the number of available items is left to the descretion
of those implementing and deploying the server.
A client may submit an [ActivityStreams] activity to the server
using a HTTP POST request to the dereferencable URI of the outbox collection.
In this case, the request's Content-Type MUST
be application/activity+json
, and the request MUST be authenticated
with credentials authorized to act on behalf of the user to whom the
outbox belongs. Such submitted activities will be added to the front of
the feed retrieved by GET requests to the same endpoint.
The inbox
stream contains all objects received by the user.
The inbox MUST be filtered according to the requester's permission; this
MAY include allowing read access only to the owning user
A server may submit a HTTP POST to the
dereferencable URI of the inbox
endpoint. This request
MUST be authenticated with the credentials of the user identified by the
actor
stanza of the activity being delivered. The request
MUST be of the [ActivityStreams] content type; it MUST be a single activity.
The server MUST perform de-duplication of activities, whereby it
discards repeats of already delivered activities (this can occur if an
activity is addressed both to a user's followers, and a specific user
which happens to follow said user, and the server has failed to
de-duplicate the recipients list, for example). Such deduplication MUST
be performed by comparing the @id
of the activities and
dropping any activities already seen.
Notification and Delivery are two closely related acts. Notifications are sent to objects and are used to perform updates on the social graph, whilst delivery is the act of inserting an activity into a recipient agent's inbox
Activity distribution and access control is per the audience targetting properties from the [ActivityStreams] specification. For each entry in the addressing properties of an object, the server shall
@type
) to discover its activity-inbox address
For federated servers performing delivery to a 3rd party server, delivery SHOULD be performed asynchronously to completion of the original activity submission request, and SHOULD additionally retry delivery to recipients if it fails due to network error
If no recipients are specified, the user's preferred default audience should be applied. The default value for the default audience is implementation specific but MAY be the user's followers collection
In addition to delivery to recipients, the server MUST also perform notification as specified by 8.2 Notification
When a user creates an activity (by submitting it to their outbox), the server should perform notification. Notification is the process of propogating awareness of the new activity to the activity's origin server such that the origin can act upon the activity (for example, notification that a user has liked an object is used to update the object's like count) and distribute the activity to ensure that it is propogated to the whole social graph which received the original object.
Notifications shall be sent to each of the following objects:
An object notified of an activity MUST deliver that activity to all recipients of the object and in addition notify all share activities of the object.
In addition to [ActivityStreams] collections and objects, Activities may additionally be addressed to the special "public" audience denoted by the object
{ "@context": "http://www.w3.org/ns/activitystreams", "@id": "http://activityschema.org/collection/public", "@type": "Collection" }
Activities addressed to this special URI shall be accessible to all users, without authentication.
For the purposes of delivery, the server shall treat the public collection as if it contains the same entries as the user's followers collection.
TODO: New URI? Can we get as:public in the schema or such?
There is the ability to submit binary data such as images, video or other
binary data you wish to use in activitypub. This is done by means of submitting
the binary data to the user's file
endpoint. The request MUST contain
the HTTP headers Content-Type
and Content-Length
. Upon
successful submission a response containing the object with an ID is returned that
can be posted to the users outbox.
An example response for an image I might upload is
:{ "@context": "", "@id": "http://example.com/~erik/photos/1", "@type": "Image", "url": [ { "@type": "Link", "href": "http://example.com/~erik/photos/1.png", "mediaType": "image/png" } ] }
There are objects which have a content
property, the value of which
is provided by the user. These can be for example note, blog, image, etc.
The core of any [ActivityStreams] based protocol is activities within. Users post activities to their outbox, from which they are distributed to recipients' inboxes. ActivityPub places no restrictions on the activities which may be distributed; however, it defines certain activities with special behaviors
The Create
activity is used to when posting a new object. This has the
side effect that of the object that they are posting is being created.
The Update
activity is used when updating an already existing object.
The object should be modified to reflect the new structure in defined in the update
activity.
The Delete
activity is used to delete an already existing object. This
MUST leave a shell of the object that will be displayed in activities which reference
the deleted object. If the deleted object is requested the server should respond with
the HTTP 410 Gone status code.
A deleted object:
{ "@context": "http://www.w3.org/ns/activitystreams", "@id": "https://example.com/~alice/note/72", "@type": "Note", "published": "2015-02-10T15:04:55Z", "updated": "2015-02-10T15:04:55Z", "deleted": "2015-02-10T15:04:55Z", }
The Follow
activity is used to subscribe to the activities of another user.
Once the user has followed a user, activities shared with the Follows of that user
SHOULD be added to the actors's inbox.
The Add
activity is used to add the object to the collection specified in the
target
property of the activity.
The Remove
activity is used to remove the object from the collection specified in the
target
property of the activity.
The Block
activity is used to indicate that the actor does not want a user (defined in
the object
property) to be able to interact with objects posted by the user. The
server SHOULD prevent the user from interacting with any object posted by the actor.
The Undo
activity is used to undo a previous activity.
For example, Undo
may be used to undo a previous Like
or Follow
.
The undo activity and the activity being undone MUST both have the same author.
Side effects (such as adding activities to a user's inbox after a Follow
) should be undone, to the extent possible.
There are some exceptions where there is an existing and explicit "inverse activity" which should be used instead.
Create
based activities should instead use Delete
, and Add
activities should use Remove
.