Abstract

This specification details a model for representing potential and completed activities using the JSON format.

Author's Note

This section is non-normative.

This draft is heavily influenced by the JSON Activity Streams 1.0 specification originally co-authored by Martin Atkins, Will Norris, Chris Messina, Monica Wilkinson, Rob Dolin and James Snell. The author is very thankful for their significant contributions and gladly stands on their shoulders. Some portions of the original text of Activity Streams 1.0 are used in this document.

Status of This Document

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 was published by the Social Web Working Group as a 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 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.

Table of Contents

1. Introduction

In the most basic sense, an "Activity" is a semantic description of an action. It is the goal of this specification to provide a JSON-based syntax that is sufficient to express metadata about activities in a rich, human-friendly but machine-processable and extensible manner. This can include constructing natural-language descriptions or visual representations about the activity, associating actionable information with various types of objects, communicating or recording activity logs, or delegation of potential actions to other applications.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

1.1 Relationship to JSON Activity Streams 1.0

This section is non-normative.

The JSON Activity Streams 1.0 [AS1] specification was published in May of 2011 and provided a baseline extensible syntax for the expression of completed activities. This specification builds upon that initial foundation by incorporating lessons learned through extensive implementation, community feedback and related ongoing work from a variety of other communities.

While the syntax defined by this specification diverges from that defined by JSON Activity Streams 1.0, the fundamental model defined by that original specification remains intact. Specific processing rules are defined by this specification that allow existing Activity Streams 1.0 documents to be mapped to and processed as an Activity Streams 2.0 document.

This specification incorporates several existing extensions to the 1.0 syntax directly into the 2.0 model. These include portions of the Activity Streams 1.0 Base Schema, Audience Targeting, Responses, and Priority extensions.

1.2 Serialization Notes

This specification describes a JSON-based [RFC7159] serialization syntax for the Activity Vocabulary that follows the conventions defined by the [JSON-LD] specification. While serialization forms other than JSON-LD are possible, alternatives are not discussed by this document.

When serialized, absent properties are represented by either (a) setting the property value to null, or (b) by omitting the property declaration altogether at the option of the publisher; these representations are semantically equivalent. If a property has an array value, the absence of any items in that array MUST be represented by omitting the property entirely or by setting the value to null. The appropriate interpretation of an omitted or explicitly null value is that no value has been assigned as opposed to the view that the given value is empty or nil.

This specification uses IRIs [RFC3987]. Every URI [RFC3986] is also an IRI, so a URI may be used wherever an IRI is named. There are two special considerations: (1) when an IRI that is not also a URI is given for dereferencing, it MUST be mapped to a URI using the steps in Section 3.1 of [RFC3987] and (2) when an IRI is serving as an "id" value, it MUST NOT be so mapped.

Unless otherwise specified, all properties with date and time values MUST conform to the "date-time" production in [RFC3339], with an uppercase "T" character used to separate date and time, and an uppercase "Z" character in the absence of a numeric time zone offset. All such timestamps SHOULD be represented relative to Coordinated Universal Time (UTC).

An Activity Streams Document is a JSON-LD document whose root value is an Activity Streams Object of any type and whose MIME media type is "application/activity+json".

Activity Streams 2.0 documents MUST be serialized using the UTF-8 character encoding.

The serialized JSON form of an Activity Streams 2.0 document MUST be consistent with what would be produced by the standard JSON-LD 1.0 Processing Algorithms and API [JSON-LD-API] Compaction Algorithm using, at least, the normative JSON-LD @context definition provided here. Implementations MAY augment the provided @context with additional @context definitions but MUST NOT override or change the normative context. Implementations MAY also include in the serialized JSON document additional properties and values not defined in the JSON-LD @context with the understanding that any such properties will likely be unsupported and ignored by consuming implementations that use the standard JSON-LD algorithms. See the Extensibility section for more information on handling extensions within Activity Streams 2.0 documents.

2. Examples

This section is non-normative.

Following are three examples of activities with varying degrees of detail. Each of the examples uses an implied JSON-LD @context equal to that provided here.

Note that the Activity Streams JSON-LD @context maps the prefix "as:" to the base URI "http://www.w3.org/ns/activitystreams#". This means that terms such as "as:Activity" are equivalent to the expanded form "http://www.w3.org/ns/activitystreams#Activity". In order to best illustrate that implementors MUST support both forms, both the compact and expanded forms are used interchangeably by the examples in this document.

Each example is shown using the normative JSON-LD serialization defined by this specification along with generally equivalent, non-normative Microdata, RDFa, Microformats, and Turtle serializations. These non-JSON-LD alternatives are included solely for illustrative purposes.

2.1 Editor's Notes

This section is non-normative.

The Microdata, RDFa and Microformats examples included in this document are purely informative and may not currently reflect actual implementation experience or accepted best practices for each format. These alternate serializations may be removed from future iterations of this document and moved to a separate informative WG Note.

The examples included in this document all use HTTP URLs for @id values. These values are not limited to URLs and it is perfectly legal to use HTTPS URLs or any URI, URN, or IRI value for the @id.

2.2 Minimal Activity

Fig. 1 Expresses the statement 'http://www.test.example/martin' created 'http://example.org/foo.jpg'. No additional detail is given.
Example 1
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Create",
  "actor": "http://www.test.example/martin",
  "object": "http://example.org/foo.jpg"
}

2.3 Basic activity with some additional detail

Fig. 2 Expresses the statement "Martin Smith added an article to the blog 'Martin's Blog' at 3:04 PM UTC on February 2, 2015." Some additional details about the article, actor and target blog are given using properties defined by the Activity Streams 2.0 Vocabulary.
Example 6
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Add",
  "published": "2015-02-10T15:04:55Z",
  "actor": {
   "@type": "Person",
   "@id": "http://www.test.example/martin",
   "displayName": "Martin Smith",
   "url": "http://example.org/martin",
   "image": {
     "@type": "Link",
     "href": "http://example.org/martin/image.jpg",
     "mediaType": "image/jpeg"
   }
  },
  "object" : {
   "@id": "http://www.test.example/blog/abc123/xyz",
   "@type": "Article",
   "url": "http://example.org/blog/2011/02/entry",
   "displayName": "Why I love Activity Streams"
  },
  "target" : {
   "@id": "http://example.org/blog/",
   "@type": "OrderedCollection",
   "displayName": "Martin's Blog"
  }
}

2.4 An extended activity

Fig. 3 A more extensive, single-entry "Activity Stream" follows.
Example 11
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Collection",
  "totalItems": 1,
  "items" : [
    {
      "@type": "Add",
      "published": "2011-02-10T15:04:55Z",
      "generator": "http://example.org/activities-app",
      "displayNameMap": {
        "en": "Martin added a new image to his album.",
        "ga": "Martin phost le fisean nua a albam."
      },
      "actor": {
        "@type": "Person",
        "@id": "http://www.test.example/martin",
        "displayName": "Martin Smith",
        "url": "http://example.org/martin",
        "image": {
          "@type": "Link",
          "href": "http://example.org/martin/image",
          "mediaType": "image/jpeg",
          "width": 250,
          "height": 250
        }
      },
      "object" : {
        "@type": "Image",
        "@id": "http://example.org/album/my_fluffy_cat",
        "preview": {
          "@type": "Link",
          "href": "http://example.org/album/my_fluffy_cat_thumb.jpg",
          "mediaType": "image/jpeg"
        },
        "url": [
          {
            "@type": "Link",
            "href": "http://example.org/album/my_fluffy_cat.jpg",
            "mediaType": "image/jpeg"
          },
          {
            "@type": "Link",
            "href": "http://example.org/album/my_fluffy_cat.png",
            "mediaType": "image/png"
          }
        ]
      },
      "target": {
        "@type": "Album",
        "@id": "http://example.org/album/",
        "displayNameMap": {
          "en": "Martin's Photo Album",
          "ga": "Grianghraif Mairtin"
        },
        "image": {
          "@type": "Link",
          "href": "http://example.org/album/thumbnail.jpg",
          "mediaType": "image/jpeg"
        }
      }
    }
  ]
}

3. Model

The Activity Vocabulary defines the abstract model for Activity Streams 2.0. The vocabulary is segmented into a set of nine core classes and an extended set of Activity and Object types common to most social Web applications. The core classes include: Object, Link, Actor, Activity, IntransitiveActivity, Collection, OrderedCollection, CollectionPage, and OrderedCollectionPage. Each of these classes is described and illustrated below. The extended Activity and Object types are defined normatively in the Activity Vocabulary specification.

3.1 Object

The Object class is the primary base class for the Activity Streams vocabulary.

In addition to having a global identifier (expressed as an absolute IRI using the JSON-LD @id keyword) and an "object type" (expressed using the JSON-LD @type keyword), all instances of the Object class share a common set of properties normatively defined by the Activity Vocabulary. These include: alias | attachment | attributedTo | content | context | contentMap | displayName | displayNameMap | endTime | generator | icon | image | inReplyTo | location | preview | published | replies | scope | startTime | summary | summaryMap | tag | title | titleMap | updated | url | to | bto | cc | bcc

Previous versions of the Activity Streams format used the objectType property to identify the object type. The objectType property MUST NOT be used within an Activity Streams 2.0 document to represent object type.

While all properties are optional, all Object instances SHOULD at least contain either the displayName or displayNameMap.

Fig. 4 Following is an example Object that uses the JSON-LD @id and @type keywords to express the global identifier and object type:
Example 16
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@id": "http://example.org/foo",
  "@type": "Note",
  "displayName": "This is a note",
  "attributedTo": {
    "@id": "http://joe.website.example/",
    "@type": "Person",
    "displayName": "Joe Smith"
  },
  "published": "2014-08-21T12:34:56Z"
}

Implementations MUST treat all object types in an Activity Streams document as subclasses of Object unless the object is a Link.

Fig. 5 For instance, in the following example, the value of the actor property is considered to be an instance of the Object class while the value of the object property is not:
Example 21
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@id": "http://example.org/foo",
  "@type": "Create",
  "displayName": "A Test",
  "actor": {
    "@type": "Person",
    "@id": "http://example.org/~sally",
    "displayName": "Sally"
  },
  "object": {
    "@type": "Link",
    "href": "http://example.org/posts/1"
  }
}

The Activity Vocabulary defines a broad range of Object types that are common to many social Web applications. This specification stops short of defining semantically specific properties for most of these objects. External vocabularies can be used to express additional detail not covered by the Activity Vocabulary.

Furthermore, while implementations are free to introduce new types of Objects beyond those defined by the Activity Vocabulary, interoperability issues can arise when applications rely too much on extension types that are not recognized by other implementations. Care should be taken to not unduly overlap with or duplicate the existing Object types. For instance, some vocabularies (e.g. The Good Relations Vocabulary) define their own classes for describing locations. An implementation that wishes, for example, to use a http://purl.org/goodrelations/v1#Location as an object type SHOULD also identify the object as being both a Place and an http://purl.org/goodrelations/v1#Location, as illustrated in the following:

Fig. 6 An Object that is both a Place and a gr:Location:
Example 26
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {
      "gr": "http://purl.org/goodrelations/v1#"
    }
  ],
  "@type": ["Place", "gr:Location"],
  "displayName": "Sally's Restaurant",
  "longitude": 12.34,
  "latitude": 56.78,
  "gr:category": "restaurants/french_restaurants"
}

Certain properties defined by some External Vocabularies can overlap or duplicate those defined by the Activity Vocabulary. Where such overlap exists, for the sake of consistent interoperability, implementers MUST favor the use of properties defined by the Activity Vocabulary.

3.2 Natural Language Values

Several properties defined by the Vocabulary are defined as having natural language values. These are representations of human-readable character sequences using one or more languages. Within the JSON-LD serialization, they are expressed as either (1) a single JSON string or (2) a JSON object mapping [RFC5646] Language-Tags to localized, equivalent translations of the same string value. In [JSON-LD], such constructs are referred to as "Language Maps". In the serialized JSON-LD, these two forms are differentiated using a simple property naming convention, for instance: "displayName" identifies the JSON string form for the displayName property while "displayNameMap" represents the Language Map form.

Fig. 7 A single displayName String value without language information:
Example 31
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Object",
  "displayName": "This is the title"
}
Fig. 8 Multiple, language-specific values:
Example 36
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Object",
  "displayNameMap": {
    "en": "This is the title",
    "fr": "C'est le titre",
    "sp": "Este es el titulo"
  }
}

Every key in the Language Map form MUST be a valid [RFC5646] Language-Tag. The associated values MUST be Strings.

The Activity Vocabulary defines four specific natural language values: displayName, title, summary, and content. Accordingly, the Activity Streams JSON-LD @context definition respectively maps the terms "displayName", "title", "summary", and "content" for representing the JSON string forms and the terms "displayNameMap", "titleMap", "summaryMap", and "contentMap" for representing the Language Map forms.

The default language for document or an individual object can be established using the JSON-LD @language keyword within a @context definition. For instance:

Fig. 9 Establishing a default language context:
Example 41
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {"@language": "en"}
  ],
  "@type": "Object",
  "displayName": "This is the title"
}

The JSON-LD format generally supports one additional way of associating language tag information with a literal string value using what JSON-LD calls a "value object", as illustrated below:

Fig. 10 Specifying language in a JSON-LD value object:
Example 46
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Object",
  "displayName": {
    "@value": "This is the title",
    "@language": "en"
  }
}

Activity Streams 2.0 implementations SHOULD NOT use JSON-LD value objects in this manner. Implementations SHOULD, instead, use the Language Map form. The one situation where use of the value object cannot be avoided is when a default language context has been established and a particular language-sensitive field needs to be explicitly excluded from that context, as in the following example:

Fig. 11 Excluding a natural language property from the language context:
Example 51
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    { "@language": "en" }
  ],
  "@type": "Object",
  "displayName": {
    "@value": "This is the title"
  }
}

By explicitly omitting the @language from the value of displayName in the JSON-LD example, the displayName is excluded from the default language context. However, because this mechanism requires specific understanding of JSON-LD algorithms, and makes the publisher's intention less obvious and visible, implementations SHOULD avoid such cases as much as possible.

3.4 Actor

Actor objects are specializations of the base Object type that represent entities capable of carrying out an Activity. The Actor class is the base class for all Actor objects. The Activity Vocabulary provides the normative definition of six specific types of Actors: Application | Group | Organization | Person | Process | Service.

This specification intentionally defines Actors in only the most generalized way, stopping short of defining semantically specific properties for each. All Actor objects are specializations of Object and inherit all of the core properties common to all Objects. External vocabularies can be used to express additional detail not covered by the Activity Vocabulary. VCard [vcard-rdf] SHOULD be used to provide additional metadata for Person, Group, and Organization instances.

Fig. 16 An Activity with a Person actor:
Example 76
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Create",
  "actor": {
    "@type": "Person",
    "@id": "http://sally.example.org",
    "displayName": "Sally Smith"
  },
  "object": {
    "@type": "Note",
    "content": "This is a simple note"
  }
}
Fig. 17 An Activity with a Person actor extended with VCard properties:
Example 81
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {"vcard": "http://www.w3.org/2006/vcard/ns#"}
  ],
  "@type": "Create",
  "actor": {
    "@type": "Person",
    "@id": "http://sally.example.org",
    "displayName": "Sally Smith",
    "vcard:given-name": "Sally",
    "vcard:family-name": "Smith"
  },
  "object": {
    "@type": "Note",
    "content": "This is a simple note"
  }
}

While implementations are free to introduce new types of Actors beyond those defined by the Activity Vocabulary, interoperability issues can arise when applications rely too much on extension types that are not recognized by other implementations. Care should be taken to not unduly overlap with or duplicate the existing Actor types. For instance, some vocabularies (e.g. VCard) define their own classes for describing people. An implementation that wishes, for example, to use a vcard:Individual as an Actor SHOULD identify that Actor as being both a Person and an vcard:Individual, as illustrated in the following:

Fig. 18 An Actor that is both a Person and a vcard:Individual:
Example 86
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {"vcard": "http://www.w3.org/2006/vcard/ns#"}
  ],
  "@type": "Create",
  "actor": {
    "@type": ["Person", "vcard:Individual"],
    "@id": "http://sally.example.org",
    "displayName": "Sally Smith",
    "vcard:given-name": "Sally",
    "vcard:family-name": "Smith"
  },
  "object": {
    "@type": "Note",
    "content": "This is a simple note"
  }
}

3.5 Activity

Activity objects are specializations of the base Object type that provide information about actions that have either already occurred, are in the process of occurring, or may occur in the future.

In addition to common properties supported by all Object instances, Activity objects support the following additional properties defined by the Vocabulary: actor | object | target | origin | result | priority | instrument

The JSON-LD @type keyword is used to identify the type of action the Activity Statement represents. Previous versions of the Activity Streams format used the verb property to identify the action type. The verb MUST NOT be used within an Activity Streams 2.0 Activity to represent the action type.

Fig. 19 The following example illustrates a simple Activity:
Example 91
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Like",
  "@id": "http://www.test.example/activiy/1",
  "actor": "http://example.org/profiles/joe",
  "object": "http://example.com/notes/1",
  "published": "2014-09-30T12:34:56Z"
}

The Activity Vocabulary defines a broad range of Activity types that are common to many social Web applications. This specification stops short of defining semantically specific properties for most of these activities. External vocabularies can be used to express additional detail not covered by the Activity Vocabulary.

Furthermore, while implementations are free to introduce new types of Activites beyond those defined by the Activity Vocabulary, interoperability issues can arise when applications rely too much on extension types that are not recognized by other implementations. Care should be taken to not unduly overlap with or duplicate the existing Activity types. For instance, some vocabularies (e.g. Schema.org) define their own classes for describing actions. An implementation that wishes, for example, to use http://schema.org/LikeAction as an Activity SHOULD identify that Object as being both a Like and an http://schema.org/LikeAction, as illustrated in the following:

Fig. 20 An Activity that is both a Like and a http://schema.org/LikeAction:
Example 96
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": ["Like", "http://schema.org/LikeAction"],
  "@id": "http://www.test.example/activiy/1",
  "actor": "http://example.org/profiles/joe",
  "object": "http://example.com/notes/1",
  "published": "2014-09-30T12:34:56Z"
}

Implementations are free to use Activity objects in both passive and imperative operations. In the passive sense, the Activity is used to record that an activity has or is occurring. In the imperative sense, the Activity can be used as a form of command, instructing an application to modify state in some manner consistent with the action being described. However, because this specification does not define a normative processing model that constrains how applications make use of the format, the distinction been whether an Activity statement is intended to be interpreted as a passive notification or as an imperative command can vary across implementations.

3.6 Collection

Collection objects are a specialization of the base Object that act as a container for other Objects or Links.

In addition to the base properties inherited by all Objects, all Collection types contain the additional properties: items | totalItems | first | last | current

The items within a Collection can be ordered or unordered. The OrderedCollection type can be used to identify a Collection whose items are always ordered. In the JSON-LD serialization, the unordered items of a Collection are represented using the items property while ordered items are represented using the orderedItems property.

The normative JSON-LD @context definition maps each of the items and orderedItems properties to the Activity Vocabulary items term. The orderedItems term, however, is defined in the JSON-LD @context as @container = @list, indicating that it's members are strictly ordered.

Fig. 21 The following is a simple unordered collection:
Example 101
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Collection",
  "totalItems": 2,
  "items": [
    {
      "@type": "Create",
      "actor": "http://www.test.example/sally",
      "object": "http://example.org/foo"
    },
    {
      "@type": "Like",
      "actor": "http://www.test.example/joe",
      "object": "http://example.org/foo"
    }
  ]
}
Fig. 22 The following is a simple ordered collection:
Example 106
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "OrderedCollection",
  "totalItems": 2,
  "orderedItems": [
    {
      "@type": "Create",
      "actor": "http://www.test.example/sally",
      "object": "http://example.org/foo"
    },
    {
      "@type": "Like",
      "actor": "http://www.test.example/joe",
      "object": "http://example.org/foo"
    }
  ]
}

3.6.1 Collection Paging

A Collection can contain a large number of items. Often, it becomes impractical for an implementation to serialize every item contained by a Collection using the items (or orderedItems) property alone. In such cases, the items within a Collection can be divided into distinct subsets or "pages". A page is represented using the CollectionPage type.

The CollectionPage type extends from the base Collection type and inherits all of it's properties. The following additional properties can also be specified: partOf | first | next | prev | last | current |

The partOf property identifies the Collection to which the items contained by the CollectionPage belong.

The first, next, prev, last, and current properties are used to reference other CollectionPage instances that contain additional subsets of items from the parent collection.

As with Collection objects, the items within a CollectionPage might be ordered or unordered. The OrderedCollectionPage type can be used to identify a page whose items are strictly ordered.

The OrderedCollectionPage type extends from both CollectionPage and OrderedCollection. In addition to the properties inherited from each of those, the OrderedCollectionPage may contain an additional startIndex property whose value indicates the relative index position of the first item contained by the page within the OrderedCollection to which the page belongs.

Fig. 23 An illustration of the relationship between Collection, OrderedCollection, CollectionPage, and OrderedCollectionPage:
Collection Class Model

Whether ordered or not, the pages of a Collection are typically arranged in a sequence (either a singly or doubly-linked list). The first property is used to identify the first page in this sequence, while the last property is used to identify the final page in the sequence. The prev and next properties identify the pages immediately before and immediately following, respectively.

Fig. 24 A visualization of the Collection paging model:
The Paging Model

The current property identifies a page containing the subset of items in the Collection that have been created or updated most recently.

The values for the first, last, next, prev, and current properties can be either a single CollectionPage or a Link referencing a separate resource containing a CollectionPage.

Fig. 25 The following is a simple unordered collection with paging:
Example 111
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Collection",
  "@id": "http://example.org/foo",
  "totalItems": 10,
  "first": {
    "@type": "CollectionPage",
    "@id": "http://example.org/foo?page=1",
    "partOf": "http://example.org/foo",
    "next": "http://example.org/foo?page=2",
    "items": [
      {
        "@type": "Create",
        "actor": "http://www.test.example/sally",
        "object": "http://example.org/foo"
      }
    ]
  }
}

Using paging with an OrderedCollection can be tricky because there are no guarantees that implementations will process the sequence of pages in any predictable order. Implementations that wish to reconstruct the appropriate complete ordering of member items in the logical collection should navigate to the first (or last) page in the sequence then recursively follow the next (or prev) link until all pages have been processed. If the pages of an OrderedCollection are not instances of OrderedCollectionPage, an implementation will have no reliable means of reconstructing the appropriate ordering of items.

4. Audience Targeting

Conceptually, every Object has both a Primary and Secondary audience. The Primary audience consists of those entities directly involved or owning the object. The Secondary audience consists of the collection of entities sharing an interest in the object but who might not be directly involved (e.g."followers").

For instance, suppose a social network of three individuals: Bob, Joe and Jane. Bob and Joe are each friends with Jane but are not friends with one another. Bob has chosen to "follow" activities for which Jane is directly involved. Jane shares a file with Joe.

In this example, Jane and Joe are each directly involved in the file sharing activity and together make up the Primary Audience for that event. Bob, having an interest in activities involving Jane, is the Secondary Audience. Knowing this, a system that produces or consumes the activity can intelligently notify each person of the event.

While there are means (based on the action type, actor, object and target of the activity) to infer the primary audience for many types of activities, heuristics do not work in every case and do not provide a means of identifying the secondary audience. The to, cc, bto and bcc properties MAY be used within an Object to explicitly identify the Primary and Secondary audiences.

The prototypical use case for an Object containing these properties is the publication and redistribution of objects through an intermediary. That is, an event source generates the object and publishes it to the intermediary which determines a subset of items to display to specific individual users or groups. Such a determination can be made, in part, by identifying the Primary and Secondary Audiences for each object.

When the event source generates the object and specifies values for the to and cc fields, the intermediary SHOULD redistribute that object with the values of those fields intact, allowing any processor to see who the object has been targeted to. This is precisely the same model used by the to and cc fields in email systems.

There are situations, however, in which disclosing the identity of specific members of the audience may be inappropriate. For instance, a user may not wish to let other users know that they are interested in various topics, individuals or types of events. To support this option, an implementation generating an object MAY use the bto and bcc properties to list entities to whom the object should be privately targeted. When an intermediary receives an object containing these properties, it MUST remove those values prior to redistributing the object. The intent is that systems MUST consider entities listed within the bto and bcc properties as part of the Primary and Secondary audience but MUST NOT disclose that fact to any other party.

Audience targeting information included within an Object only describes the intent of the object creator. With clear exception given to the appropriate handling of bto and bcc, this specification leaves it up to implementations to determine how the audience targeting information is used.

5. Deprecated Activity Streams 1.0 Syntax

The JSON syntax defined by this specification differs somewhat from that defined in the original JSON Activity Streams 1.0 [AS1] specification in ways that are not backwards compatible. Implementations can choose to continue supporting the JSON Activity Streams 1.0 syntax but SHOULD consider it to be deprecated. This means that while implementations MAY continue to consume the 1.0 syntax, they SHOULD NOT output the 1.0 syntax unless specifically interacting with older non-2.0 compliant implementations.

Specifically:

  1. Implementations MUST use the "application/stream+json" MIME media type when producing a JSON serialization using the Activity Streams 1.0 syntax, and "application/activity+json" when producing a serialization conforming to the 2.0 syntax.
  2. Implementations that process serializations identified using either the "application/stream+json" or the more generic "application/json" MIME media type MUST follow the syntax and processing rules set by [AS1]. The 2.0 syntax and processing rules apply only when handling serializations using the "application/activity+json" media type.
  3. When processing Activity Streams 1.0 documents using a JSON-LD processing model, implementations MUST use the special AS 1.0 to AS 2.0 expansion @context definition provided here to produce the JSON-LD expanded representation. Refer to the JSON-LD Processing Algorithms and API for details.
  4. When processing Activity Streams 1.0 documents and converting those to 2.0, implementations MUST treat id as an alias for the JSON-LD @id key word; and the objectType and verb properties as aliases for the JSON-LD @type keyword.
  5. This document redefines the displayName, title, content and summary properties as natural language values which means their values can be expressed as either a String or a JSON-LD Language Map. In the 1.0 syntax, these are expressed solely as String values. Because the 1.0 values are a valid subset allowed by this specification, implementations are not required to take any specific action to continue supporting those values.
  6. This document redefines a large number of common properties defined originally as Objects in 1.0 as either Objects or Links. The JSON-LD serialization allows such property values to be expressed as either an IRI String, an JSON object, or an Array of IRI Strings and JSON objects. Because the 1.0 values are a valid subset allowed by this specification, existing implementations are not required to take any specific action to continue supporting those values.
  7. This specification deprecates the upstreamDuplicates and downstreamDuplicates properties defined by Activity Streams 1.0 and does not provide a replacement. This is due largely to lack of any reasonable implementation evidence. While the upstreamDuplicates and downstreamDuplicates properties MAY continue to be used, implementations SHOULD avoid them.
  8. In Activity Streams 1.0, the "post" verb was defined to describe the action of both creating an object and "posting" or uploading it to a service. This specification replaces the "post" verb with separate Create and Add Activity types. When processing Activity Streams 1.0 documents and converting those into 2.0, implementations SHOULD treat instances of the "post" verb as equivalent to Create if there is no target property specified; and equivalent to Add if there is a target property specified.

By following these requirements, all JSON Activity Streams 1.0 serializations can be processed successfully by 2.0 implementations.

6. Extensibility

In Activity Streams 2.0, an "extension" is any property not defined by the Activity Vocabulary. Consuming implementations that encounter unfamiliar extensions MUST NOT stop processing or signal an error and MUST continue processing the items as if those properties were not present. Note that support for extensions can vary across implementations and no normative processing model for extensions is defined. Accordingly, implementations that rely too heavily on the use of extensions may experience reduced interoperability with other implementations.

It is important to note that the JSON-LD Processing Algorithms [JSON-LD-API], as currently defined, will silently ignore any property not defined in a JSON-LD @context. Implementations that publish Activity Streams 2.0 documents containing extension properties SHOULD provide a @context definition for all extensions.

It is also important to note that there are valid JSON constructs which cannot be used within a JSON-LD document. For instance, JSON-LD forbids "arrays of arrays" as used, for example, by the popular GeoJSON specification. While implementations are free to use such constructs as extensions within an Activity Streams 2.0 document, consumers that use the standard JSON-LD Processing Algorithms will be required to either ignore such extensions or map those to alternative compatible constructs prior to applying the JSON-LD algorithms. Simple GeoJSON Points, for instance, can be mapped to Place objects, while more complex geometries can be converted to GeoSparql "Well-Known Text" representations as illustrated in the non-normative examples below:

Fig. 26 GeoJSON Point Coordinates:
Example 116
{
  "type": "Point",
  "coordinates": [36.74, -119.77]
}
Fig. 27 The Equivalent Place alternative:
Example 117
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Place",
  "latitude": 36.74,
  "longitude": -119.77
}
Fig. 28 GeoJSON Polygon Coordinates:
Example 122
{
  "type": "Polygon",
  "coordinates": [
    [
      [100.0, 0.0],
      [101.0, 0.0],
      [101.0, 1.0],
      [100.0, 1.0],
      [100.0, 0.0]
    ]
  ]
}
Fig. 29 The Equivalent GeoSparql Well-Known-Text alternative:
Example 123
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {"gsp": "http://www.opengis.net/ont/geosparql"}
  ],
  "@type": "gsp:Geometry",
  "gsp:asWKT": "Polygon((100.0, 0.0, 101.0, 0.0, 101.0, 1.0, 100.0, 1.0, 100.0, 0.0))"
}

6.1 Re-serialization of Extensions

Implementations that parse and then reserialize Activity Streams 2.0 documents that contain extension properties SHOULD take sufficient care to ensure that extension properties used within the original document are preserved and serialized appropriately.

For instance, consider the following simple Activity Stream object containing hypothetical foo and bar extension properties. The foo extension is defined within the JSON-LD @context while the bar extension property is not.

Fig. 30 A simple extended Object
Example 128
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {"foo": "http://example.org/foo"}
  ],
  "@type": "Note",
  "content": "This is a simple note",
  "foo": 123,
  "bar": 321
}

An implementation that receives this Note object can choose to parse the object as an ordinary JSON object or it can use the standard JSON-LD Expansion algorithm.

If the implementation chooses to parse the object as ordinary JSON and then reserializes the object (e.g. for storage or redistribution), then it would simply preserve the values of the @context, foo and bar properties as they are and include those in the reserialized output.

However, if the implementation chooses to use the JSON-LD expansion algorithm, the @context will be removed from the expanded result and the bar property will be mapped to the "blank node" _:bar.

Fig. 31 The JSON-LD Expanded version of the previous object:
Example 129
[
  {
    "@type": ["http://www.w3.org/ns/activitystreams#Note"],
    "http://www.w3.org/ns/activitystreams#content": [
      {
        "@value": "This is a simple note"
      }
    ],
    "http://example.org/foo": [
      {
        "@value": 123,
        "@type": "http://www.w3.org/2001/XMLSchema#integer"
      }
    ],
    "_:bar": [
      {
        "@value": "321"
      }
    ]
  }
]

If this document is then reserialized using only the normative Activity Streams 2.0 context, the JSON-LD compacted form would be:

Fig. 32 The reserialized compacted form:
Example 130
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Note",
  "content": "This is a simple note",
  "http://example.org/foo": 123,
  "bar": 321
}

While this is close, the use of fully expanded URI label for the foo property is not ideal. To ensure that the reserialized object is serialized correctly, implementations that perform JSON-LD expansion of received documents SHOULD, as much as possible, preserve the original @context used when performing the JSON-LD expansion, then reuse that when reserializing the object into the JSON-LD compacted form.

Fig. 33 The reserialized compacted form using the original @context
Example 131
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {"foo": "http://example.org/foo"}
  ],
  "@type": "Note",
  "content": "This is a simple note",
  "foo": 123,
  "bar": 321
}

6.2 Aggregation of Extensions

Implementations that collect and aggregate Activity Streams objects from multiple sources may often need to deal with conflicting or incompatible extensions.

For instance, an implementation could receive both of the following objects from clients. In each, a foo extension property is defined and used but the definition of each are incompatible:

Fig. 34 foo as an integer
Example 132
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {
      "foo": {
        "@id": "http://example.org/foo",
        "@type": "xsd:integer"
      }
    }
  ],
  "@type": "Note",
  "content": "This is a simple note",
  "foo": 123
}
Fig. 35 foo as a date-time
Example 133
{
  "@context": [
    "http://www.w3.org/ns/activitystreams",
    {
      "foo": {
        "@id": "http://example.net/fooDate",
        "@type": "xsd:dateTime"
      }
    }
  ],
  "@type": "Note",
  "content": "This is another note",
  "foo": "2015-12-11T12:34:56Z"
}

An implementation that wishes to include both objects within a Collection serialized into JSON-LD compacted form would face a number of issues due to the conflicting definitions of the foo property. To serialize correctly, the implementation SHOULD preserve the @context property for each of the original objects and include those directly within the serialized result:

Fig. 36 A Collection containing both objects:
Example 134
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Collection",
  "items": [
    {
      "@context": [
        "http://www.w3.org/ns/activitystreams",
        {
          "foo": {
            "@id": "http://example.org/foo",
            "@type": "xsd:integer"
          }
        }
      ],
      "@type": "Note",
      "content": "This is a simple note",
      "foo": 123
    },
    {
      "@context": [
        "http://www.w3.org/ns/activitystreams",
        {
          "foo": {
            "@id": "http://example.net/fooDate",
            "@type": "xsd:dateTime"
          }
        }
      ],
      "@type": "Note",
      "content": "This is another note",
      "foo": "2015-12-11T12:34:56Z"
    }
  ]
}

While the serialized result is verbose, the use of the localized @context definitions ensures that the conflicting extension properties will be serialized appropriately.

7. Mentions, Tags and Other Common Social Microsyntaxes

Many social software systems use special text-based microsyntaxes that allow users to define special addressing for notifications, linking, or categorization within objects. For example, including text such as "@username" within an object's content will often route the object to a special "mentions" or "inbox" stream for a particular user. Likewise, including text such as "#topic" within the object's content will often mark the object as being related to the topic "topic". Such mechanisms are commonly referred to as "mentions" and "hashtags", respectively.

While such microsyntaxes MAY be used within the values of the content, displayName, summary, and title properties on an Activity Streams Object, implementations SHOULD NOT be required to parse the values of those properties in order to determine the appropriate routing of notifications, categorization or linking between objects. Instead, publishers SHOULD make appropriate use of the Activity Streams Vocabulary terms provided specifically for these purposes.

For example, suppose that an author wishes to send a note of thanks to another user named "sally" with a hashtag of "#givingthanks". A typical way this message would appear within the content of a note is shown below:

Fig. 37 A simple note with a mention an a hashtag:
 "Thank you @sally for all your hard work! #givingthanks" 

A typical social software implementation would typically render such a content such that "@sally" is replaced with a hyperlink to "sally"'s social profile page and "#givingthanks" is replaced with a hyperlink to a listing of other notes that have been "tagged" with the same topic. Most implementations would also send a special notification to sally letting her know that a note mentioning her has been created.

The following illustrates an equivalent Activity Streams Note object:

Fig. 38 Mentions and Tags within an Activity Streams Note
Example 135
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Note",
  "content": "Thank you <a href=\"http://sally.example.org\">@sally</a>
              for all your hard work!
              <a href=\"http://example.org/tags/givingthanks\">#givingthanks</a>",
  "to": {
    "@type": "Person",
    "@id": "http://sally.example.org",
    "alias": "@sally"
  },
  "tag": {
    "@id": "http://example.org/tags/givingthanks",
    "alias": "#givingthanks"
  }
}

The to property indicates that the user "@sally" is to be considered part of the primary audience of the note and should therefore receive notification. The tag property associates the Note with a reference to "http://example.org/tags/givingthanks". Note that the note's content still includes the "@sally" and "#givingthanks" microsyntaxes but that consuming implementations are not required to parse those in order to make the appropriate associations.

In the case a publisher wishes to indicate a mention without an associated notification, the publisher can use the Mention object type as a value of the tag property. The Mention object is a subclass of Link.

Fig. 39 Mentions and Tags within an Activity Streams Note
Example 138
{
  "@context": "http://www.w3.org/ns/activitystreams",
  "@type": "Note",
  "content": "Thank you @sally for all your hard work! #givingthanks",
  "tag": [
    {
      "@type": "Mention",
      "href": "http://example.org/people/sally",
      "displayName": "@sally"
    },
    {
      "@id": "http://example.org/tags/givingthanks",
      "alias": "#givingthanks"
    }
  ]
}

8. Security Considerations

Publishers or Consumers implementing Activity Streams as a stream of public data may also want to consider the potential for unsolicited commercial or malicious content and should take preventative measures to recognize such content and either identify it or not include it in their implementations.

Publishers should take reasonable measures to ensure potentially malicious user input such as cross-site scripting attacks are not included in the Activity Streams data they publish.

Consumers that re-emit ingested content to end-users MUST take reasonable measures if emitting ingested content to make sure potentially malicious ingested input is not re-emitted.

Consumers that re-emit ingested content for crawling by search engines should take reasonable measures to limit any use of their site as a Search Engine Optimization loophole. This may include converting untrusted hyperlinks to text or including a rel="nofollow" attribute.

Consumers should be aware of the potential for spoofing attacks where the attacker publishes activities or objects with falsified property values with the intent of injecting malicious content, hiding or corrupting legitimate content, or misleading users.

Activity Streams are JSON Documents and are subject to the same security considerations described in [RFC7159].

Activity Streams implementations handle URIs. See Section 7 of [RFC3986].

Activity Streams implementations handle IRIs. See Section 8 of [RFC3987].

9. IANA Considerations

9.1 The application/activity+json Media Type

This specification registers the application/activity+json MIME Media Type specifically for identifying documents conforming to the Activity Streams 2.0 format.

Type name: application
Subtype name: activity+json
Required parameters: None
Optional parameters: profile: The profile parameter for the application/activity+json media type allows one or more profile URIs to be specified. These profile URIs have the identifier semantics defined in [RFC6906]. The "profile" media type parameter MUST be quoted. It contains a non-empty list of space-separated URIs (the profile URIs).
profile-param = "profile=" profile-value
profile-value = <"> profile-URI 0*( 1*SP profile-URI ) <">
profile-URI   = URI
The "URI" in the above grammar refers to the "URI" as defined in Section 3 of [RFC3986].
Encoding considerations: Resources that use the "application/activity+json" Media Type are required to conform to all of the requirements for the "application/json" Media Type and are therefore subject to the same encoding considerations specified in Section 11 of [RFC7159].
Security considerations: As defined in this specification.
Contact: James M Snell <jasnell@gmail.com>

9.2 The application/stream+json Media Type

This specification registers the application/stream+json MIME Media Type specifically for identifying documents conforming to the JSON Activity Streams 1.0 [AS1] format.

Type name: application
Subtype name: stream+json
Required parameters: None
Optional parameters: profile: The profile parameter for the application/stream+json media type allows one or more profile URIs to be specified. These profile URIs have the identifier semantics defined in [RFC6906]. The "profile" media type parameter MUST be quoted. It contains a non-empty list of space-separated URIs (the profile URIs).
profile-param = "profile=" profile-value
profile-value = <"> profile-URI 0*( 1*SP profile-URI ) <">
profile-URI   = URI
The "URI" in the above grammar refers to the "URI" as defined in Section 3 of [RFC3986].
Encoding considerations: Resources that use the "application/stream+json" Media Type are required to conform to all of the requirements for the "application/json" Media Type and are therefore subject to the same encoding considerations specified in Section 11 of [RFC7159].
Security considerations: As defined in [AS1]
Contact: James M Snell <jasnell@gmail.com>

A. Acknowledgements

The author wishes to thank the Activity Streams community and implementers for their support, encouragement, and enthusiasm including but not limited to: Abdul Qabiz, Adina Levin, Adrian Chan, Adriana Javier, Alan Hoffman, Alex Kessinger, Alexander Ovchinnikov, Alexander Zhuravlev, Alexandre Loureiro Solleiro, Amy Walgenbach, Andres Vidal, Angel Robert Marquez, Ari Steinberg, Arjan Scherpenisse, Arne Roomann-Kurrik, Beau Lebens, Ben Hedrington, Ben Metcalfe, Ben Werdmuller, Benjamin Goering, Bill de hOra, Bo Xing, Bob Aman, Bob Wyman, Brett Slatkin, Brian Walsh, Brynn Evans, Charlie Cauthen, Chris Chabot, Chris Messina, Chris Toomey, Christian Crumlish, Dan Brickley, Dan Scott, Daniel Chapman, Danny Ayers, Dare Obasanjo, Darren Bounds, David Cramer, David Nelson, David Recordon, DeWitt Clinton, Douglas Pearce, Ed Summers, Elias Bizannes, Elisabeth Norris, Eric Marcoullier, Eric Woods, Evan Prodromou, Gee-Hsien Chuang, Greg Biggers, Gregory Foster, Henry Saputra, Hillary Madsen, Howard Liptzin, Hung Tran, Ian Kennedy, Ian Mulvany, Ivan Pulleyn, Jacob Kim, James Falkner, James Pike, James Walker, Jason Kahn, Jason Kantz, Jeff Kunins, Jeff Martin, Jian Lin, Johannes Ernst, John Panzer, Jon Lebkowsky, Jon Paul Davies, Jonathan Coffman, Jonathan Dugan, Joseph Boyle, Joseph Holsten, Joseph Smarr, Josh Brewer, Jud Valeski, Julien Chaumond, Julien Genestoux, Jyri Engestroem, Kaliya Hamlin, Kevin Marks, Laurent Eschenauer, Laurie Voss, Leah Culver, Libby Miller, Manu Mukerji, Mark Weitzel, Marko Degenkolb, Marshall Kirkpatrick, Martin Atkins, Martin Svensson, Marty Alchin, Mary Hoder, Matt Leventi, Matt Wilkinson, Matthias Mueller-Prove, Max Engel, Max Wegmueller, Melvin Carvalho, Michael Buckbee, Michael Chan, Michael Richardson, Michael Sullivan, Mike Macgirvin, Mislav Marohnić, Mo Jangda, Monica Wilkinson, Nate Benes, NeilFred Picciotto, Nick Howard, Nick Lothian, Nissan Dookeran, Nitya Narasimhan, Pablo Martin, Padraic Brady, Pat Cappelaere, Patrick Aljord, Peter Ferne, Peter Reiser, Peter Saint-Andre, Phil Wolff, Philip (flip) Kromer, Richard Cunningham, Richard Zhao, Rick Severson, Robert Hall, Robert Langbert, Robert Dolin, Robin Cover, Ryan Boyd, Sam Sethi, Scott Raymond, Scott Seely, Simon Grant, Simon Wistow, Stephen Garcia, Stephen Sisk, Stephen Paul Weber, Steve Ivy, Steve Midgley, Steven Livingstone-Perez, Sylvain Carle, Sylvain Hellegouarch, Tantek Çelik, Tatu Saloranta, Tim Moore, Timothy Young, Todd Barnard, Tosh Meston, Tyler Gillies, Will Norris, Zach Copley, Laurent-Walter Goix, Matthew Marum, Andy Smith, and Zach Shepherd.

B. Summary of Changes

2015-01-16

2014-11-06

2014-09-30

C. Table of Figures

D. References

D.1 Normative references

[AS1]
J. Snell; M. Atkins; W. Norris; C. Messina; M. Wilkinson; R. Dolin. JSON Activity Streams 1.0. unofficial. URL: http://activitystrea.ms/specs/json/1.0/
[HTML5]
Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. HTML5. 28 October 2014. W3C Recommendation. URL: http://www.w3.org/TR/html5/
[JSON-LD]
Manu Sporny; Gregg Kellogg; Markus Lanthaler. JSON-LD 1.0. 16 January 2014. W3C Recommendation. URL: http://www.w3.org/TR/json-ld/
[JSON-LD-API]
Markus Lanthaler; Gregg Kellogg; Manu Sporny. JSON-LD 1.0 Processing Algorithms and API. 16 January 2014. W3C Recommendation. URL: http://www.w3.org/TR/json-ld-api/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC3339]
G. Klyne; C. Newman. Date and Time on the Internet: Timestamps. July 2002. Proposed Standard. URL: https://tools.ietf.org/html/rfc3339
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. January 2005. Internet Standard. URL: https://tools.ietf.org/html/rfc3986
[RFC3987]
M. Duerst; M. Suignard. Internationalized Resource Identifiers (IRIs). January 2005. Proposed Standard. URL: https://tools.ietf.org/html/rfc3987
[RFC5988]
M. Nottingham. Web Linking. October 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
[RFC6906]
E. Wilde. The 'profile' Link Relation Type. March 2013. Informational. URL: https://tools.ietf.org/html/rfc6906
[RFC7159]
T. Bray, Ed.. The JavaScript Object Notation (JSON) Data Interchange Format. March 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7159

D.2 Informative references

[RFC5646]
A. Phillips, Ed.; M. Davis, Ed.. Tags for Identifying Languages. September 2009. Best Current Practice. URL: https://tools.ietf.org/html/rfc5646
[vcard-rdf]
Renato Iannella; James McKinney. vCard Ontology - for describing People and Organizations. 22 May 2014. W3C Note. URL: http://www.w3.org/TR/vcard-rdf/