OpenSocialDraft

Recent site activity

RESTful Protocol Specification


The RESTful API serves as a common protocol understood by all OpenSocial 0.9-compliant clients and servers.

Notation and Conventions

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]. Domain name examples use [RFC2606].

Overview

This API defines a language and platform neutral protocol for clients to interact with OpenSocial container servers outside of gadgets on a web page. As a protocol, it is intended to be reasonably easy to implement in any language and on any platform. It should also be usable across a range of clients, from gadgets operating within a web page to servers communicating to synchronize data about a user.

The protocol operates primarily in terms of resources and operations on them. It is defined on top of the HTTP protocol, and uses the standard HTTP methods (GET, POST, PUT, DELETE, etc.) to retrieve and change server state. 


No single data representation is ideal for every client. This protocol defines representations for each resource in three widely supported formats, JSON [RFC4627], XML, and Atom/AtomPub [RFC4287][RFC5023], using a set of generic mapping rules. The mapping rules allow a server to write to a single interface rather than implementing the protocol three times.

OpenSocial container servers are free to define additional representations but MUST support at least the JSON and Atom formats for all resources and XML for the people calls. XML MAY be supported for the rest of the resources.


The protocol defines Activity, Album, AppData, Group, MediaItem, Person, and UserPreference resources. Most operations consist of retrieving (GET), updating (PUT), creating (POST or PUT), or destroying (DELETE) these resources. It also specifies an optional partial update feature which avoids sending large resources over the wire to update just one field. 


OpenSocial API Background details the underlying concepts used below; this document assumes familiarity with the OpenSocial model.

Data Representations

Each resource has three representations, as JSON, XML, and Atom. All data must be representable in each format. The XML and JSON formats have a one to one mapping while the Atom format is defined separately for each type of object and collection. Throughout this document, examples will only be given in JSON and Atom. The XML representation can be mapped directly from the JSON and MUST conform to the XSD in Section 12.


Each resource is represented as a hierarchical tree of elements. Ordering of elements within a parent element may or may not be significant, depending on the context. Mapping consists of converting between the internal hierarchy and the JSON/XML or Atom protocol format.


The set of allowed fields in each type of data is the same as the set documented in Section 11 (field names)


The general rules for mapping between the Atom and JSON formats are as follows. Each data type may add additional aliasing rules.

  • The default location for all data in the Atom format is in atom:entry/atom:content/datatype, where datatype is a root node naming the type of data delivered: <person>, <group>, <activity>, <album>, <mediaItem>, <userPreferences> or <appData>.
  • The field names are specified at the end of this document in camelCase
  • Strings are represented as strings in both formats.
  • Dates and timestamps are represented as strings containing AtomPub (RFC3339) format date-time elements; see section 3.3 of [RFC4287]. These are also known as "XSD Dates". In cases where only a day-of-the-year is desired, e.g., a birthday, the year SHOULD be specified as 0000.
  • Enums are represented as objects with "displayvalue" (localizable, customizable string) and "key" (key) fields.
  • Arrays are represented as arrays in the JSON representation and as repeated fields in the XML representation.
  • Sub-objects are represented as sub-elements in both formats.
  • Fields are placed directly in the root object in the JSON format. In the Atom format, they are by default placed under atom:content/datatype (e.g., atom:content/person for person data). Some fields are 'hoisted' and aliased to standard Atom fields directly underneath atom:entry. There are three standard aliases that apply to all data types:
    • atom:entry/atom:id aliases the "id" field. The JSON format id is the OpenSocial globally unique ID, which consists of the container domain (e.g., example.org) followed by a colon and the container's id for that person. The container specific id can only contain letters (A-Za-z), numbers (0-9), dots (.), hyphens (-) and underscores (_). For example, example.org:78gh37261ddfdf. In the Atom format, it is translated into the required IRI (RFC3987) data type by prepending "urn:guid:" to the OpenSocial ID string. These rules are intended to make mapping IDs between the RESTful API and the JS API straightforward while preserving global uniqueness.
    • atom:entry/atom:updated aliases the JSON field indicating the most recent modification the container considers significant (POSTED_TIME for Activity), or the generation time if no better information is available.
    • atom:entry/atom:published aliases the JSON field indicating the object creation time (POSTED_TIME for Activity).

Examples of the primary types of data follow. Each example shows both representations, JSON and Atom, with the payload data highlighted for ease of comparison.

Responses

The structure of the response object returned from a successful request for the JSON or XML formats is as follows. The root element isresponse, which is shown explicitly as the root element in XML format, and is the anonymous root object returned when the format is json (i.e. in JSON, the response returned is the object value of the response node). The response node MUST contain the following child nodes, and MAY contain additional nodes that the Service Provider wishes to add to expose additional data. Note that startIndexitemsPerPage, and totalResults are based on OpenSearch definitions but are required elements in an OpenSocial context.


  • startIndex: the index of the first result returned in this response, relative to the starting index of all results that would be returned if no startIndex had been requested. In general, this will be equal to the value requested by the startIndex, or 1 if no specific startIndex was requested.
  • itemsPerPage: the number of results returned per page in this response. In general, this will be equal to the count Query Parameter, but MAY be less if the Service Provider is unwilling to return as many results per page as requested, or if there are less than the requested number of results left to return when starting at the current startIndex.
  • totalResults: the total number of results that would be returned if there were no startIndex or count specified. This value tells the Consumer how many total results to expect, regardless of the current pagination being used, but taking into account the current filtering options in the request.
  • entry: an array of objects, one for each item matching the request, as defined in Section 7.2 (entry Element). For consistency of parsing, if the request could possibly return multiple items (as is normally the case), this value MUST always be an array of results, even if there happens to be 0 or 1 matching results. If the request is specifically for a single contact (e.g. because the request contains Additional Path Information like /@me/@all/{id} or /@me/@self), then entry MUST be an object containing the single item returned (i.e. "entry": [ { /* first item */ } ] and "entry": { /* only item */ } respectively).


For example:

application/json representation:

{
"startIndex" : 1
"itemsPerPage" : 10
"totalResults" : 100,
"entry" : [
{...first item...},
{...second item...}
...
]
}

or, for only one item:

{
  "startIndex" : 1
  "itemsPerPage" : 10
  "totalResults" : 100,
  "entry" : {...only item...}
}


xml representation:

<response>
<startIndex> 1 </startIndex>
<itemsPerPage> 10 <itemsPerPage>
<totalResults> 100 <totalResults>
<entry>...first item...</entry>
<entry>...second item...</entry> 
...
</response>

or, for only one item:

<response>
<startIndex> 1 </startIndex>
<itemsPerPage> 10 <itemsPerPage>
<totalResults> 100 <totalResults>
<entry>...first item...<entry>
</response>


The atom format uses the JSON to Atom mapping rules described above and has a different base format than the XML: 


application/atom+xml representation:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:osearch="http://a9.com/-/spec/opensearch/1.1/">
<id>tag:example.org,2008:...</id><!-- container identifier, OpenSocial spec year, query identifier -->
<title>Brief feed description</title><!-- person.displayName -->
<updated>2008-12-01T00:00:00Z</updated><!-- most recent entry.updated or datetime.utcnow() -->
<category term="person" scheme="http://ns.opensocial.org/2008/opensocial" /> <!-- object type as category, mapped to OpenSocial namespace -->
<link rel="self" type="application/atom+xml" href="http://example.org/...?format=atom" />
<link rel="alternate" type="application/json" href="http://example.org/..." /><!-- alternate response format(s) for the given request-->
<osearch:startIndex>1</osearch:startIndex>
<osearch:itemsPerPage>2</osearch:itemsPerPage>
<osearch:totalResults>10</osearch:totalResults>
<entry>...first item...</entry>
<entry>...second item...</entry>
</feed>

Person

A Person contains social network data about a single person. The same record is used for contacts/friends and for profiles.

See Section 11 (field names) for a full list of available fields and their types. See also the general mapping rules in section 2.


A minimal Person example:

application/json representation:


{

  "id" : "example.org:34KJDCSKJN2HHF0DW20394",
"displayName" : "Janey",
"name" : {"formatted" : "Jane Doe"},
"gender" : "female"
}

application/xml representation:

<person xmlns="http://ns.opensocial.org/2008/opensocial">
  <id>example.org:34KJDCSKJN2HHF0DW20394</id>
  <displayName>Janey</displayName>
  <name>
    <formatted>Jane Doe</formatted>
  </name>
  <gender>female</gender>
</person>


application/atom+xml representation:

<entry xmlns="http://www.w3.org/2005/Atom">
<id>example.org:34KJDCSKJN2HHF0DW20394</id><!-- person.id -->
<title>Janey</title><!-- person.displayName -->
<updated>2008-03-15T10:00:00Z</updated><!-- last profile edit, or datetime.utcnow() -->
<author><name>Janey</name></author><!-- person.displayName -->
<content type="application/xml">
<person xmlns="http://ns.opensocial.org/2008/opensocial">
<id>example.org:34KJDCSKJN2HHF0DW20394</id>
<displayName>Janey</displayName>
  <name>
<formatted>Jane Doe</formatted>
  </name>
<gender>female</gender>
</person>
</content>
</entry>


Note: The atom:summary element is the appropriate place to put a text or HTML representation of the structured data present in the content element, and the atom:title element is the appropriate place to copy a short descriptive name for the entry, such as name.unstructured. Servers MAY choose to add these or other fields to make their feeds more useful for generic aggregators or tools.

Group

OpenSocial Groups are owned by people, and are used to tag or categorize people and their relationships. The RESTful API supports querying for the available groups for a given user. The groups are returned as a collection. Each group has a display name, an identifier which is unique within the groups owned by that person, and a URI link.

A Group example:

application/json representation:


{
"id" : "example.org:34KJDCSKJN2HHF0DW20394/friends",
"title" : "Peeps",
}

application/xml representation:

<group xmlns="http://ns.opensocial.org/2008/opensocial">
  <id>example.org:34KJDCSKJN2HHF0DW20394/friends</id>
  <title>Peeps</title>
</group>

application/atom+xml representation:

<entry xmlns="http://www.w3.org/2005/Atom">
<id>example.org:34KJDCSKJN2HHF0DW20394/friends</id><!-- group.id -->
<title>Friends of John Smith</title><!-- group.title + person.displayName -->
<updated>2008-03-15T10:00:00Z</updated><!-- last significant group change, or datetime.utcnow() -->
<author><name>John Smith</name></author><!-- person.displayName -->
<link rel="alternate" type="application/json" href="http://example.org/people/example.org:34KJDCSKJN2HHF0DW20394/@friends" />
<link rel="alternate" type="application/atom+xml" href="http://example.org/people/example.org:34KJDCSKJN2HHF0DW20394/@friends?format=atom" />
<link rel="alternate" type="application/xml" href="http://example.org/people/example.org:34KJDCSKJN2HHF0DW20394/@friends?format=xml" />
<content type="application/xml">
<group xmlns="http://ns.opensocial.org/2008/opensocial">
<id>example.org:34KJDCSKJN2HHF0DW20394/friends</id>
  <title>Peeps</title>
</group>
</entry>

Groups only appear within Group Collections and are used to retrieve a list of available groups for a given person.

Activity

An OpenSocial Activity represents a short summary or notification of a timestamped event, often with pointers for more information.

See Section 11 (field names) for a full list of available fields and their types. Activities have extensive Atom hoisting rules to ensure maximum compatibility with standard feed processing code:

  • atom:entry/atom:title aliases "title"
  • atom:entry/atom:summary aliases "body"
  • atom:entry/atom:link@rel="self" aliases "url"
  • atom:entry/atom:icon aliases "faviconUrl"
  • atom:entry/atom:source/atom:title aliases "streamTitle"
  • atom:entry/atom:source/atom:link@rel="self" aliases "streamUrl"
  • atom:entry/atom:generator/atom:uri aliases "appId"
  • atom:entry/atom:author/atom:uri aliases "userId"


A minimal Activity example:

application/json representation:


{
"id" : "http://example.org/activities/example.org:87ead8dead6beef/self/af3778",
"title" : "<a href=\"foo\">some activity</a>",
"updated" : "2008-02-20T23:35:37.266Z",
"body" : "Some details for some activity",
"bodyId" : "383777272",
"url" : "http://api.example.org/activity/feeds/.../af3778",
"userId" : "example.org:34KJDCSKJN2HHF0DW20394"
}

application/xml representation:

<activity xmlns="http://ns.opensocial.org/2008/opensocial">
  <id>http://example.org/activities/example.org:87ead8dead6beef/self/af3778</id>
  <title>&lt;a href=\"foo\"&gt;some activity&lt;/a&gt;</title>
  <updated>2008-02-20T23:35:37.266Z</updated>
  <body>Some details for some activity</body>
  <bodyId>383777272</bodyId>
  <url>http://api.example.org/activity/feeds/.../af3778</url>
  <userId>example.org:34KJDCSKJN2HHF0DW20394</userId>
</activity>


application/atom+xml representation:

<entry xmlns="http://www.w3.org/2005/Atom">
<id>http://example.org/activities/example.org:87ead8dead6beef/self/af3778</id>
<title>some activity</title><!-- activity.title or activity.titleId -->
<updated>2008-02-20T23:35:37.266Z</updated><!-- postedTime, or datetime.utcnow() -->
<author>
<uri>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</uri>
<name>
John Smith</name>
</author>
<link rel="self" type="application/atom+xml" href="http://api.example.org/activity/feeds/.../af3778" />
<link rel="alternate" type="application/json" href="http://example.org/activities/example.org:87ead8dead6beef/self/af3778" /><!-- alternate JSON response -->
<content type="application/xml">
<activity xmlns="http://ns.opensocial.org/2008/opensocial">
<id>http://example.org/activities/example.org:87ead8dead6beef/self/af3778</id>
<title type="html">&lt;a href=\"foo\"&gt;some activity&lt;/a&gt;</title>
<updated>2008-02-20T23:35:37.266Z</updated>
<body>Some details for some activity</body>
<bodyId>383777272</bodyId>
<url>http://api.example.org/activity/feeds/.../af3778</url>
<userId>example.org:34KJDCSKJN2HHF0DW20394</userId>
</activity>
</content>
</entry>

Note: The title field is a string that may only have the following html tags: <b>, <i>, <a>, <span>. 

The container may ignore this formatting when rendering the activity.

AppData

AppData stores uninterpreted key/value pairs on behalf of an application. The standard unit of AppData is all of the key/value pairs stored for a given app on behalf of a given user; however, the API supports other types of queries (detailed below). To retrieve a subset of fields, use the fields= selector syntax (detailed below).


An isolated AppData example

The first example is of a collection of key/value pairs for a particular application/user pair:

application/json representation:


{
"pokes" : 3,
"last_poke" : "2008-02-13T18:30:02Z"
}

application/xml representation:

<appData xmlns="http://ns.opensocial.org/2008/opensocial">
  <entry>
    <key>pokes</key>
    <value>3</value>
  </entry>
  <entry>
    <key>last_poke</key>
    <value>2008-02-13T18:30:02Z</value>
  </entry>
</appData>


application/atom+xml representation:

<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<appData xmlns="http://ns.opensocial.org/2008/opensocial">
<pokes>3</pokes>
<last_poke>2008-02-13T18:30:02Z</last_poke>
</appData>
</content>
<title/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<url>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</url>
<name>
John Smith</name>
</author>
<id>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</id>
</entry>

An AppData Collection Example

In this example, a client has requested a collection of data that spans multiple users. The result is a collection which, by default, is given a special default JSON representation as a mapping from users to their data. 


application/json representation:

(maps directly to the xml format)

{
"entry" : {
"example.org:34KJDCSKJN2HHF0DW20394" : {"pokes" : 3, "last_poke" : "2008-02-13T18:30:02Z" },
"example.org:58UIDCSIOP233FDKK3HD44" : {"pokes" : 2, "last_poke" : "2007-12-16T18:30:02Z" }
}
}

application/atom+xml representation:

<feed xmlns="http://www.w3.org/2005/Atom>
<id>...</id>
<title>...</title>
<entry>
<content type="text/xml">
<appData>
<pokes>3</pokes>
<last_poke>"2008-02-13T18:30:02Z"</last_poke>
</appData>
</content>
<title/>
<updated>2008-02-13T18:30:02Z</updated>
<author><url>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</url></author>
<id>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</id>
</entry>
<entry>
<content type="text/xml">
<appData>
<pokes>2</pokes>
<last_poke>"2007-12-16T18:30:02Z"</last_poke>
</appData>
</content>
<title/>
<updated>2007-12-16T18:30:02Z</updated>
<author><url>uurn:guid:example.org:58UIDCSIOP233FDKK3HD44</url></author>
<id>urn:guid:example.org:58UIDCSIOP233FDKK3HD44</id>
</entry>
</feed>

The data within each field is assumed to be in JSON format and is otherwise uninterpreted.

User Preferences

UserPreferences stores user preferences on behalf of an application. The
standard unit of UserPreferences is all of the preference information
stored for a given application on behalf of a given user. The API also
supports other types of queries, described in section 6.5. To retrieve a
subset of fields, use the fields= selector syntax, described in section
6.6.

An isolated Preferences example

The first example is of a preference request returning all preferences
for an application and user:

application/json representation:

{

       "lang": "en",

       "country": "US",

       "moduleId": "24341",

       "arrayValues": {

              "favoriteColors": [ "blue", "red"],

              "statusMessages": [ "online", "offline"]

       },

       "boolValues": {

              "boolVal1": "true",

              "boolVal2": "false"

       },

       "numberValues":  {

              "millisecondsOnline": "1234567",

              "highScore": "8600"

              "e": "2.71828",

              "pi": "3.14159"

       },

       "stringValues": {

              "stringVal1": "hi",

              "stringVal2": "bye"

       }

}



application/xml representation:

<userPreferences xmlns="http://ns.opensocial.org/2008/opensocial">

  <lang>en</lang>

  <country>US</country>

  <moduleId>24341</moduleId>

  <arrayValues>

    <entry>

      <key>favoriteColors</key>

      <value>

        <entry>blue</entry>

        <entry>red</entry>

      </value>

    </entry>

    <entry>

      <key>statusMessages</key>

      <value>

        <entry>online</entry>

        <entry>offline</entry>

      </value>

    </entry>

  </arrayValues>

  <boolValues>

    <entry>

      <key>boolVal1</key>

      <value>true</value>

    </entry>

    <entry>

      <key>boolVal2</key>

      <value>false</value>

    </entry>

  </boolValues>

  <numberValues>

    <entry>

      <key>millisecOnline</key>

      <value>1234567</value>

    </entry>

    <entry>

      <key>highScore</key>

      <value>8600</value>

    </entry>

    <entry>

      <key>e</key>

      <value>2.71828</value>

    </entry>

    <entry>

      <key>pi</key>

      <value>3.14159</value>

    </entry>

  </numberValues>

  <stringValues>

    <entry>

      <key> stringVal1</key>

      <value>hi</value>

    </entry>

    <entry>

      <key> stringVal2</key>

      <value>bye</value>

    </entry>

  </stringValues>

</userPreferences>

application/atom+xml representation

<entry xmlns="http://www.w3.org/2005/Atom">
  <content type="application/xml">
    <userPreferences xmlns="http://ns.opensocial.org/2008/opensocial">
      <lang>en</lang>
      <country>US</country>
      <moduleId>24341</moduleId>
      <arrayValues>
        <entry>
          <key>favoriteColors</key>
          <value>
            <entry>blue</entry>
            <entry>red</entry>
          </value>
        </entry>
        <entry>
          <key>statusMessages</key>
          <value>
            <entry>online</entry>
            <entry>offline</entry>
          </value>
        </entry>
      </arrayValues>
      <boolValues>
        <entry>
          <key>boolVal1</key>
          <value>true</value>
        </entry>
        <entry>
          <key>boolVal2</key>
          <value>false</value>
        </entry>
      </boolValues>
      <numberValues>
        <entry>
          <key>millisecOnline</key>
          <value>1234567</value>
        </entry>
        <entry>
          <key>highScore</key>
          <value>8600</value>
        </entry>
        <entry>
          <key>e</key>
          <value>2.71828</value>
        </entry>
        <entry>
          <key>pi</key>
          <value>3.14159</value>
        </entry>
      </numberValues>
      <stringValues>
        <entry>
          <key> stringVal1</key>
          <value>hi</value>
        </entry>
        <entry>
          <key> stringVal2</key>
          <value>bye</value>
        </entry>
      </stringValues>
    </userPreferences>
  </content>
  <title/>
  <updated>2003-12-13T18:30:02Z</updated>
  <author>
    <url>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</url>
  </author>
  <id>urn:guid:example.org:34KJDCSKJN2HHF0DW20394</id>
</entry>

Albums/MediaItem

Albums support collections of media items (video, image, sound).

A minimal album example:

application/json representation:

{
  "id" : "44332211",
  "thumbnailUrl" : "http://pages.example.org/albums/4433221-tn.png",
  "caption" : "Example Album",
  "description" : "This is an example album, and this text is an example description",
  "location" : { "latitude": 0, "longitude": 0 },
  "ownerId" : "example.org:55443322"
}


application/xml representation:

<album xmlns="http://ns.opensocial.org/2008/opensocial">
  <id>44332211</id>
  <thumbnailUrl>http://pages.example.org/albums/4433221-tn.png</thumbnailUrl>
  <caption>Example Album</caption>
  <description>This is an example album, and this text is an example description</description>
  <location>
     <latitude>0</latitude>
     <longitude>0</longitude>
  </location>
  <ownerId>example.org:55443322</ownerId>
</album>

application/atom+xml representation
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<album xmlns="http://ns.opensocial.org/2008/opensocial">
<id>44332211</id>
<thumbnailUrl>http://pages.example.org/albums/4433221-tn.png</thumbnailUrl>
<caption>Example Album</caption>
<description>This is an example album, and this text is an example description</description>
<location>
<latitude>0</latitude>
<longitude>0</longitude>
</location>
<ownerId>example.org:55443322</ownerId>
</album>
 </content>
<title/>
<updated>2003-12-13T18:30:02Z</updated>
<author><url>example.org:55443322</url></author>
<id>urn:guid:example.org:44332211</id>
</entry>

A minimal media item example:

application/json representation:


{
  "id" : "11223344",
  "thumbnail_url" : "http://pages.example.org/images/11223344-tn.png",
  "mime_type" : "image/png",
  "type" : "image",
  "url" : "http://pages.example.org/images/11223344.png",
  "album_id" : "44332211"
}

application/xml representation:
<MediaItem xmlns="http://ns.opensocial.org/2008/opensocial">
  <id>11223344</id>
  <thumbnail_url>http://pages.example.org/images/11223344-tn.png</thumbnail_url>
  <mimeType>image/png</mimeType>
  <type>image</type>
  <url>http://pages.example.org/images/11223344.png</url>
  <albumId>44332211</albumId>
<MediaItem>

application/atom+xml representation
<entry xmlns="http://www.w3.org/2005/Atom">
<content type="application/xml">
<mediaItem xmlns="http://ns.opensocial.org/2008/opensocial">
<id>11223344</id>
<thumbnail_url>http://pages.example.org/images/11223344-tn.png</thumbnail_url>
<mimeType>image/png</mimeType>
<type>image</type>
<url>http://pages.example.org/images/11223344.png</url>
<albumId>44332211</albumId>
<mediaItem>
 </content>
<title/>
<updated>2003-12-13T18:30:02Z</updated>
<author><url>example.org:55443322</url></author>
<id>urn:guid:example.org:11223344</id>
</entry>

Content Upload

Content Upload is a generic mechanism to allow for a standard way to upload content. A common place to apply content upload will be against an existing Album or MediaItem endpoint. In most scenarios an uploaded content is associated with creation of an entity. Creation of the entity routinely precedes upload of content. For example, a request to create a new media item precedes the step of uploading a photo. The requests look like:
Step 1: Create Media Item placeholder for image
Step 2: Upload Photo
The two step request process is illustrated below.

Step 1: Creating a media item (place holder for an image) in album (id:112233) by a POST request using ATOM (see section 2.7 for examples of JSON and XML)
Request
POST /album/112233/mediaitem/ HTTP/1.1
<usual headers>
Content-Type: application/atom+xml
Content-Length: length

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:osapi="http://opensocial.org/2008/opensocialapi">
  <content type="application/xml">
    <mediaitem xmlns="http://ns.opensocial.org/2008/opensocial">
      <caption>Lena</caption>
      <media_type>IMAGE</media_type>
    </mediaitem>
  </content>
  <title />
  <updated>2008-10-24T20:30:40.500Z</updated>
  <author />
</entry>

Response
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:ossearch="http://a9.com/-/spec/opensearch/1.1/">
  <author><uri>urn:guid:example.org:33445577722</uri></author>
  <link rel="next" href="http://api.example.org/..." />
  <ossearch:totalResults>100</ossearch:totalResults>
  <ossearch:startIndex>1</ossearch:startIndex>
  <ossearch:itemsPerPage>10</ossearch:itemsPerPage>
  <entry xmlns="http://www.w3.org/2005/Atom" xmlns:osapi="http://opensocial.org/2008/opensocialapi">
    <content type="application/xml">
      <mediaitem xmlns="http://ns.opensocial.org/2008/opensocial">
        <id>223344</id>
        <caption>Lena</caption>
        <media_type>IMAGE</media_type>
      </mediaitem>
    </content>
    <title />
    <updated>2008-10-24T20:30:40.500Z</updated>
    <author />
  </entry>
</feed>

The response indicates that the media item was created and media item id is 223344.Step 2: Upload the image in the media item place holder
Request
POST /album/112233/mediaitem/223344 HTTP/1.1
<usual headers>
Accept-Type: application/xml
Content-Type: image/gif
Content-Length: length

GIF89a....<binary data>

Response
<response>
  <startIndex> 1 </startindex>
  <itemsPerPage> 1 </itemsPerPage>
  <totalResults> 1 </totalResults>
  <entry> ... </entry>
</response>

Shortcut Upload Method

The shortcut upload mechanism is OPTIONAL. This two step process shown above can be merged into one by a single POST request with the content type set to the item being uploaded. The POST URL can optionally pass the attributes. The Accept-type indicates the format of the response expected.

Request
POST /album/112233/mediaitem/?caption=Lena&media_type=IMAGE HTTP/1.1
<usual headers>
Accept-Type: application/json
Content-Type: image/gif
Content-Length: length

GIF89a....<binary data>

Response
{
  "startIndex" : 1,
  "itemsPerPage" : 1,
  "totalResults" : 1,
  "entry" : {
    "id" : "223344",
    "caption" : "Lena",
    "media_type" : "IMAGE",
  }
}

Invalidation

To invalidate content a developer's backend notifies the container of the content it wishes to invalidate by making a 2-legged OAuth call to the REST/RPC endpoint with one or many keys to be invalidated. The consumer key in the 2-legged OAuth call is used by the container to identify the calling application. Keys have the following general form

 <invalidation-key> = url | <opensocial id>

When invalidating opensocial id's containers MUST support invalidating both fully qualified opensocial ids of the form "<domain>:<domain relative id>", "<domain>.<domain relative id>", as well as ids of the form "<domain relative id>".

Each request accepts a repeated group of ids.

application/json representation

 { invalidationKeys : [ <invalidation-key>, <invalidation-key>, ...] }

application/xml

 <invalidationKeys>
    <invalidationKey>...</invalidationKey>
    <invalidationKey>...</invalidationKey>
 </invalidationKeys >

Operations

OpenSocial uses standard HTTP methods: GET to retrieve, PUT to update in place, POST to create new, and DELETE to remove. POST is special; it operates on collections and creates new activities, persons, or app data within those collections, and returns the base URI for the created resource in the Location: header, per AtomPub semantics.

Restricted clients, or clients behind restricted clients, which cannot use PUT or DELETE SHOULD translate PUT and DELETE to POST operations with an additional X-HTTP-Method-Override: header:

    POST /... HTTP/1.1
...
X-HTTP-Method-Override: PUT

Servers SHOULD respond to POST+X-HTTP-Method-Override as if the content of the header were the actual operation sent.

Note: OpenSocial 0.9 does not support cross-domain JSONP (GET with callback), but servers MAY offer this as an extension. It is RECOMMENDED that such servers implement appropriate security and authorization controls.

Request Authentication and Authorization Context

Each RESTful operation has a request context that usually includes authentication and authorization information. Typically, the context information includes the requestor id (the user initiating the request) and app ID (the application, or whatever is acting as the user's agent). It may include other container-specific information.

Containers MUST be an OAuth Core 1.0 Service Provider (a web application that allows access via OAuth). Containers MAY also support other ways to establish a request context. Containers MUST also support the Consumer Request OAuth extension, in which the end user has not directly authorized the operation. Applications SHOULD ensure that the users have given prior consent, implicitly or explicitly, to the operation or class of operations. However, containers MAY require an additional prior trust relationship be established by the app in order to allow use of Consumer Request OAuth.

If a Consumer has a user identifier and wishes to indicate that the operation is being done on behalf of that particular user, it SHOULD provide the OAuth extension parameter xoauth_requestor_id with the OAuth signed parameters. Consumers SHOULD only provide this if the user has given prior consent, implicitly or explicitly, to the operation or class of operations, as it indicates that the operation is being done on behalf of the user. Container SPs MUST either honor the parameter or ignore it as if it were not provided.

Thus, a request context usually includes the requesting application (the OAuth Consumer), and may include the requesting user, either implicitly via an oauth_token or explicitly via xoauth_requestor_id. It may also include additional information via extensions or other channels (cookies, URI parameters, client SSL certificates, etc.) A container may also accept requests with no authentication or authorization (authnz) information at all for public data. A container may provide a public version (e.g., of a profile) if no authnz information is provided.

Note that the data provided for a given RESTful URI MAY vary per requestor or app. Thus, the meaning of the resource at a given URI is "the view of the information available to the current requestor/app combination". In the case where no information is available due to lack of authorization, an HTTP 401 Unauthorized response SHOULD be returned to the client. In the case where at least some view of the information is available, it SHOULD be returned using a 200 status, with a standard OAuth WWW-Authenticate: header indicating that additional information may be available when using a different authnz context.

Discovery

A container declares what collection and features it supports, and provides templates for discovering them, via a simple discovery document. A client starts the discovery process at the container's identifier URI (e.g., example.org). The full flow is available athttp://xrds-simple.net/core/1.0/; in a nutshell:

  1. Client GETs {container-url} with Accept: application/xrds+xml
  2. Container responds with either an X-XRDS-Location: header pointing to the discovery document, or the document itself.
  3. If the client received an X-XRDS-Location: header, follow it to get the discovery document.

The discovery document is an XML file in the same format used for OpenID and OAuth discovery, defined at http://xrds-simple.net/core/1.0/:

<XRDS xmlns="xri://$xrds">
<XRD xmlns:simple="http://xrds-simple.net/core/1.0" xmlns="xri://$XRD*($v*2.0)" xmlns:os="http://ns.opensocial.org/2008/opensocial" version="2.0">
<Type>xri://$xrds*simple</Type>
<Service>
<Type>http://ns.opensocial.org/2008/opensocial/people</Type>
<os:URI-Template>http://api.example.org/people/{guid}/{selector}{-prefix|/|pid}</os:URI-Template>
</Service>
<Service>
<Type>http://ns.opensocial.org/2008/opensocial/groups</Type>
<os:URI-Template>http://api.example.org/groups/{guid}</os:URI-Template>
</Service>
<Service>
<Type>http://ns.opensocial.org/2008/opensocial/activities</Type>
<os:URI-Template>http://api.example.org/activities/{guid}/{appid}/{selector}</os:URI-Template>
</Service>
<Service>
<Type>http://ns.opensocial.org//2008/opensocial/appData</Type>
<os:URI-Template>http://api.example.org/appData/{guid}/{appid}/{selector}</os:URI-Template>
</Service>
<Service>
<Type>http://ns.opensocial.org/2008/opensocial/userpreferences</Type>
<os:URI-Template>http://api.example.org/userpreferences/{guid}/{preferenceType}</os:URI-Template>
</Service>
<Service>
<Type>http://ns.opensocial.org/2008/opensocial/invalidate</Type>
<os:URI-Template>http://api.example.org/invalidate</os:URI-Template>
</Service>
<Service>
<Type>http://ns.opensocial.org/2008/opensocial/messages</Type>
<os:URI-Template>http://api.example.org/messages/{guid}/{selector}</os:URI-Template>
</Service>
<Service>
  <Type>http://ns.opensocial.org/2008/opensocial/albums</Type>
  <os:URI-Template>http://api.example.org/albums/{userId}/{groupId}/{optionalAlbumId}</os:URI-Template>
</Service>
 <Service>
 <Type>http://ns.opensocial.org/2008/opensocial/mediaItems</Type>
 <os:URI-Template>http://api.example.org/mediaitems/{userId}/{groupId}/{optionalAlbumId}/{optionalMediaItemId}</os:URI-Template>
 </Service>
</XRD>
</XRDS>

Each Service advertises a service provided by the container. Each container MUST support the service Types documented below and MAY support others by advertising them in the discovery document. Each service comprises a set of resources defined by the given URI Template (or URI, if there is only a single resource). Clients follow the URIs and instantiate the templates to find and operate on specific resources. (URI Template syntax is documented at http://www.ietf.org/internet-drafts/draft-gregorio-uritemplate-03.txt.)

The set of substitution variables is fixed for each service Type. The core set of service Types and their substitution variables is documented below. Extensions to OpenSocial SHOULD document their substitution variables; note that a reasonable place to put human readable documentation is at the namespace URI.

The Core OpenSocial Service Types

This section defines the core types that every OpenSocial container MUST support, their XRDS types, and their semantics. Unless otherwise specified, all HTTP operations are generally allowed for any URI endpoint; a container which wishes to specify the allowed operations SHOULD provide an HTTP Allow: header for each resource listing the allowed operations.

People

XRDS Type: http://ns.opensocial.org/2008/opensocial/people

guid : Container-globally-unique user identifier; identifies owner of the people data, or @me to indicate the requestor should be used 
selector : One of
  • A user-defined local group name to select a group of contacts (a collection)
  • @self to select the person record for guid
  • @all to select all the universal set of contacts (a collection)
  • @friends to select the subset of contacts which are friends (a collection)
pid : In the context of a collection selector, picks a single person record from that collection. The pid value MAY be relative to that collection.
People URI examples:
/people/{guid}/@all -- Collection of all people connected to user {guid}
/people/{guid}/@friends -- Collection of all friends of user {guid}; subset of @all
/people/{guid}/{groupid} -- Collection of all people connected to user {guid} in group {groupid}
/people/{guid}/@all/{pid} -- Individual person record for a specific person known to {guid}; shows {guid}'s view of {pid}.
/people/{guid}/@self -- Profile record for user {guid}
/people/@me/@self -- Profile record for requestor
/people/@supportedFields -- Returns all of the fields that the container supports on people objects as an array in json and a repeated list in atom.
/people/{guid}/@deleted -- This is an OPTIONAL api that will return all of the people connected to the user {guid} that have been deleted.
This should usually be combined with a updatedSince param.

Note that a given container may use alternative URI formats; for example,
  /people.cgi?guid={guid}&groupid={groupid}

is a valid URI pattern given the appropriate XRDS discovery document which allows clients to map the parameters to a concrete URI.

Friends may be added by POSTing to the appropriate collection (e.g., /people/{guid}/@friends). Containers MAY require a dual opt-in process before the friend record appears in the collection, and in this case SHOULD return a 202 Accepted response, indicating that the request is 'in flight' and may or may not be ultimately successful.


If the guid is set to -1, the value for the anonymous user MUST be returned. The value for the name and nickname fields can either be blank or set to an appropriate value such as 'Guest', 'Anonymous', etc.

Groups

XRDS Type: http://ns.opensocial.org/2008/opensocial/groups

guid : Container-globally-unique user identifier; identifies owner of the people data; can be @me to indicate auth[nz] requestor should be used.

Groups URI examples:
  /groups/{guid}                      -- Collection of groups associated with user {guid}

Activities

XRDS Type: http://ns.opensocial.org/2008/opensocial/activities

guid : Container-globally-unique user identifier; owner or recipient of the activity data, or @me to indicate the requestor should be used

selector : One of
  • A user-defined local group name to select activities from people in the group (a collection)
  • @self to select the activities for user guid (a collection)
  • @all to select all the universal set of contacts (a collection)
  • @friends to select the activities from friends only (a collection)

appId : The app id to select activities for, or @app to indicate the currently requesting application.

Activity URI examples:

/activities/{guid}/@self                -- Collection of activities generated by given user
/activities/{guid}/@self/{appid} -- Collection of activities generated by an app for a given user
/activities/{guid}/@friends -- Collection of activities for friends of the given user {guid}
/activities/{guid}/@friends/{appid} -- Collection of activities generated by an app for friends of the given user {guid}
/activities/{guid}/{groupid} -- Collection of activities for people in group {groupid} belonging to given user {uid}
/activities/{guid}/{groupid}/{appid} -- Collection of activities generated by an app for people in group {groupid} belonging to given user {uid}
/activities/{guid}/@self/{appid}/{activityid} -- Individual activity resource; usually discovered from collection
/activities/@supportedFields -- Returns all of the fields that the container supports on activity objects as an array in json and a repeated list in atom.

AppData (http://ns.opensocial.org/2008/opensocial/appData)

guid : Container-globally-unique user identifier, or @me to indicate the requestor should be used

selector : One of
  • A user-defined local group name to select appData from people in the group (a collection)
  • @self to select the appData for user guid only (a collection)
  • @all to select all the universal set of contacts (a collection)
  • @friends to select the appData from friends of guid only (a collection)

appId : The app id to select activities for, or @app to indicate the currently requesting application.

AppData URI examples:

/appData/{guid}/@self/{appid}                  -- All app data for user {guid}, app {appid}
/appData/{guid}/@friends/{appid} -- All app data for friends of user {guid} and app {appid}; read-only (only GET and HEAD supported)
/appData/{guid}/@self/{appid}?fields=highscore -- Just the highscore field for user {guid}, app {appid}

UserPreferences

XRDS Type: http://ns.opensocial.org/2008/opensocial/userpreferences

guid: Container-globally-unique user identifier or @me to indicate the requestor should be used.

preferenceType: One of [stringValues, intValues, boolValues, floatValues, arrayValues]. If not present, this is requesting/putting the entire set of UserPreferences for the guid/appid.

App ID is always mapped using the OAuth parameters.

UserPreferences reserves the following field names:

·         country: Gets the current country, returned as an ISO 3166-1 alpha-2 code.

·         lang: Gets the language to use when communicating with the user, returned as an ISO 639-1 code.

·         moduleId: Gets the module ID for the current application instance.

When no fields= filter is present in the query string, all preferences for the {guid} and {appid} are returned.

Albums

XRDS Type: http://ns.opensocial.org/2008/opensocial/albums
userId: ID of the user or @me to indicate the requestor should be used
groupId: @self: albums for the userId (support for this parameter is optional)
    @friends: friends of the userId
    @all: Albums for all of the people in that user's group.
    @groupId: Albums for all of the people in a specific group.
optionalAlbumId: Id of the album. When specified, returns media items from the album.

Album URI examples:
  A GET on /albums/@me/@self with yield an array of Albums
  A POST on /albums/@me/@self will create a new Album
  A GET on /albums/@me/@self/albumId with return only that specific album
  A PUT on /albums/@me/@self/albumId will update the album
  A DELETE on /albums/@me/@self/albumId will delete the album

MediaItems

XRDS Type: http://ns.opensocial.org/2008/opensocial/mediaItems
userId: ID of the user or @me to indicate the requestor should be used
groupId: @self: albums for the userId (support for this parameter is optional)
    @friends: friends of the userId
    @all: Albums for all of the people in that user's group.
    @groupId: Albums for all of the people in a specific group.
optionalAlbumId: Id of the album. When specified, returns media items from the album.
optionalMediaItemId: Id of a media item within an album. optionalAlbumId is required to get to a specific media item.

  A GET on /mediaitems/@me/@self/albumId with return the media items in the album
  A POST on /mediaitems/@me/@self/albumId can be used to create a new media item
  A GET on /mediaitems/@me/@self/albumId/mediaItemId will return the media item
  A PUT on /mediaitems/@me/@self/albumId/mediaItemId will update the media item
  A DELETE on /mediaitems/@me/@self/albumId/mediaItemId will delete the mediaItem

Invalidation

XRDS Type: http://ns.opensocial.org/2008/opensocial/invalidate
An application can execute an invalidation request as a POST to the REST endpoint described in the containers XRDS or as a JSON-RPC call. Response codes have the following meanings

    * 200 - Success, all invalidations processed successfully.
    * 403 - Forbidden because authentication failed.
    * 409 - The request was partially processed, the set of invalidation keys that were not honored MUST be included in the response body in the format the request was made.

Containers MAY reject invalidation requests for policy reasons. Containers MAY continue to serve content that has already been invalidated until the container is able to successfully fetch a replacement from it original source.
Examples

Invalidate the gadget spec and message bundle of an application using REST

 POST /api/rest/invalidate
 HOST opensocial.example.org
 Content-Type application/json
 {
    invalidationKeys : [ "http://www.myapp.com/gadgetpec.xml", "http://www.myapp.com/messagebundle.xml"]
 }

Invalidate content for a set of users using JSON-RPC

 POST /api/rpc
 HOST opensocial.example.org
 Content-Type application/json
 {
    method : "invalidate.post",
    params : {
      invalidationKeys : [ "example.org:12345", "example.org:4567", "3456778"]
    }
 }

Standard Query Parameters

These additional query parameters may be used with any URI above. The parameters startIndex and count are interpreted according to the OpenSearch spec.


count={count}                      -- Requests page size for paged collection. If no parameter is specified the container can choose how many items 
in the collection should be returned. However, the container SHOULD support a large default count value so that
all items can be returned by default.
filterBy={fieldname} -- For a collection, return entries filtered by the given field.
filterOp={operation} -- The operation to use when filtering a collection, defaults to "contains". Valid values are contains, equals, startsWith, and present.
filterValue={value} -- The value to use when filtering a collection. For example, filterBy=name&filterOp=startsWith&filterValue=John will
return all items whose name field starts with John. Johnny and John Doe would both be included.)
format={format} -- Format desired; one of (atom, json, xml); default is json if not provided
fields={-join|,|field} -- List of fields to include in representation or in the members of a collection. If no fields are provided it is up to
the container to decide which fields to return. However, the set MUST include the minimum set of fields.
For people this is id, name, and thumbnailUrl. For activities this is id and title.
@all is accepted to indicate returning all available fields.
networkDistance={networkDistance} -- Modifies group-relative requests (@friends, etc.) to include the transitive closure of all friends up to
{networkDistance} links away. May not be honored by the container.
sortBy={fieldname} -- For a collection, return entries sorted by the given field.
sortOrder={order} -- Can either be "ascending" or "descending", defaults to ascending. Used to sort objects in a collection.
startIndex={startIndex} -- Index into a paged collection
updatedSince={xsdDateTime} -- When specified the container should only return items whose updated date is equal to or more recent then the specified value.

Behavior of query parameters to determine if two people are friends (important part is the query string):
  /people/@me/@self?filterBy=@friends&filterOp=contains&filterValue=<someUserId>
-- This will return nothing if the other ID is not a friend, the current user if the two are friends. filterValue
may take a specific person identifier of @owner or @viewer.

To determine the mutual friends between two people (important part is the query string):
 /people/@me/@friends?filterBy=@friends&filterOp=contains&filterValue=<someUserId>
-- This will return the set of mutual friends between the current user and someUserId. filterValue may take a specific
person identifier of @owner or @viewer.


Note: The container is not required to support all values for filtering, sorting and getting the last set of updated items from a collection. If the

container does not respect the filer, sort or updatedSince param the response should contain "filtered : false", "sorted : false", or "updatedSince : false".

Security Considerations

Containers SHOULD carefully consider security. Containers MUST support OAuth but SHOULD use appropriate policies to determine allowed operations on a per-Consumer and per-user basis. Per the OAuth spec, Containers SHOULD document how a Consumer can direct a user to a Container web page to obtain an oauth_token for future use. Note that this is a vector for phishing if the user is required to enter their credentials.

Containers SHOULD support SSL connections for sensitive data as OAuth on its own does not provide encryption or message body integrity checking. Containers should base their security decisions on the type of client in use; a generally available desktop client, for example, cannot effectively protect a Consumer Secret that is installed with each client. The security of communications with a partner service, on the other hand, is dependent on the effectiveness of that service's security procedures. Containers may wish to rate limit requests from unknown clients, or require registration, in order to mitigate risk.

Containers should scope oauth_tokens as narrowly as possible (e.g., allow reading but not writing if a client only performs reads).

Concurrency Control (Optional)

This feature allows a container and client to cooperate in order to prevent multiple containers from overwriting each other's data. It uses the standard HTTP/AtomPub optimistic concurrency mechanism based on ETags (see section 9.5 of [RFC5023] for details; the same mechanism applies regardless of the data format used for the body of the PUT).

Discovery

Concurrency control is available on a resource-by-resource basis. When an updateable resource supports concurrency control, the container SHOULD supply an ETag encoding the resource's current state when supplying a representation to clients. If a resource does not support optimistic concurrency, it MUST respond to an update request containing an If-Match: header with a 403 Not Implemented error.

A server which chooses not to support optimistic concurrency SHOULD omit ETags on its responses for updateable resources. A client SHOULD assume that optimistic concurrency is not available if no ETag is present.

Semantics

When a client is given an ETag, it MAY supply that ETag in an If-Match: header on subsequent updates. The semantics are that the client can supply the new representation and the previous ETag; the server inspects the current state of the resource and applies the update if the client supplied ETag matches (meaning no intervening updates have happened), otherwise responds with a 409 Conflict error and the new ETag. Clients may then take appropriate actions to resolve the conflict, or fail the operation, depending on their needs. Clients are also free to use PUT to simply overwrite a resource with a new state at any time, ignoring possible overwriting problems.

If partial updates are supported (see below), a server MUST accept an ETag given for either a base resource or a projection of that resource upon a subsequent PUT for that resource. That is, it is legal to supply an ETag you received when GETting the full representation of a resource even if you are only PUTting back a single field. If you intend to simply overwrite that single field, then you skip sending any ETag.

Partial Updates

Partial updates avoid the need to send full representations of data on updates, especially for People and App Data. The primary use case is when a client has retrieved a full representation and subsequently wishes to send a small update to a server. In the most general case, the client may have a series of small updates (e.g., changing tags on a large number of contacts) scattered across many resources. To accomplish these partial updates we will take advantage of the "fields" parameter.


When the "fields" parameter is specified on a url, only those fields will be looked at when updating an object. If a field is in the parameter list but not part of the post, that would be considered a removal of that field. If the field is in the post but not in the parameter list a 400 bad request error will be returned. If a field is in both places then it will be updated normally.


Messaging (Optional)

A social network service may optionally expose a mechanism for retrieving and sending short messages between users. The functionality and policies are parallel to those of the JS API's requestSendMessage.

XRDS Type: http://ns.opensocial.org/2008/opensocial/messages

  • guid: as defined for people above. Generally a unique user id, however could also refer to a community, or @me to refer to the current authentication context.
  • msgcolluid : Container-globally-unique message collection identifier can be:
    • A container specific identifier of a collection of messages
    • @inbox to indicate the collection of all messages sent to the user
    • @outbox to indicate the collection of all messages sent by the user and used as a special endpoint for posting outbound messages.
  • msgid: Container unique message id.

Discovery

If a container supports messaging, it advertises a "messages" Service in its discovery document:

<Service>
<Type>http://ns.opensocial.org/messages/0.8</Type>
<os:URI-Template>http://api.example.org/messages/{guid}{-prefix|/|msgcollid}{-prefix|/|msgid}</os:URI-Template>
</Service>

Semantics

Basic REST operations are available for Message Collections:

  • GET /messages/{guid} - Returns list of message collections for user specified in guid
  • POST /messages/{guid} - Posting data here results in a new message collection
  • PUT /messages/{guid}/{msgcollid} - Updates the data for a message collection, for example, renaming.

All standard collection handling parameters work here, including sortBy, filterBy etc.

When you have a message collection you can then perform operations on messages.

To get a list of messages in a specific collection, send a request to the following endpoint. Specify the message collection ID (msgcollid) or @inbox/@outbox for all messages. You can also use the filterBy, and sortBy parameters to return a smaller, sorted subset of messages.

  • GET /messages/{guid}/{msgcollid}

To create a message and place it in a queue, a client POSTs a message to an 'outbox' collection:

  • POST /messages/{guid}/@outbox

The outbox is owned by the source user. Placing a message in the outbox requests that the message be delivered to one or more recipients as specified in the message. Containers are free to filter or alter the message according to their own policies (such as security or rate limiting policies).

Access to individual messages is also available. You can retrieve an individual message by sending a GET request with a valid msgid value and a valid message collection. A PUT request can alter fields of an individual message (i.e. marking the message as 'read'). A DELETE request will remove the specified message from the given collection. A DELETE from the @all collection should remove the message from all collections in the system. Here are some example requests:

  • GET /messages/{guid}/@all/{msgid}
  • PUT /messages/{guid}/@all/{msgid}
  • DELETE /messages/{guid}/{msgcollid}/{msgid}

A Message example follows. For brevity, details of the 'sender' field, an OpenSocial Person, are omitted.

application/json representation:

{
"id" : "http://example.org/inbox/message/{msgid}",

"recipients" : ["example.org:AD38B3886625AAF", "example.org:997638BAA6F25AD"],

"sender" : "{ "id" : ... }",

"title" : "You have a new messge from Joe",

"titleId" : "541141091700",
"body" : "Short message from Joe to some friend\/s",

"bodyId" : "5491155811231",
"type" : "privateMessage",
"status" : "unread",
"data" : "..."
}

application/xml representation:

<message xmlns="http://ns.opensocial.org/2008/opensocial">
<id>http://example.org/inbox/message/{msgid}</id>
<recipient>example.org:AD38B3886625AAF</recipient>
<recipient>example.org:997638BAA6F25AD</recipient>
<sender>
<person>...</person>
</sender>
<title>You have a new messge from Joe</title>
<titleId>541141091700</titleId>
<updated>2008-09-29T23:35:37.266Z</updated>
<body>Short message from Joe to some friend\/s</body>
<bodyId>5491155811231</bodyId>
<type>privateMessage</type>
<status>unread</status>
<data>...</data>
</message>

application/atom+xml representation:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:osapi="http://opensocial.org/2008/opensocialapi">
<osapi:recipient>example.org:AD38B3886625AAF</osapi:recipient>
<osapi:recipient>example.org:997638BAA6F25AD</osapi:recipient>
<sender><person>...</person></sender>
<title>You have a new message from Joe</title>
<id>http://example.org/inbox/message/{msgid}</id>
<link rel="alternate" href="http://app.example.org/inbox/message/{msgid}"/>
<content>Short message from Joe to some friend/s</content>
<status>UNREAD</status>
<data>...</data>
</entry>


The recipient may also include a type identifier. The osapi:recipient supports two formats:

  1. For people: [container]:[identifier]

  2. Specifying a group or a person: [container]:[group|person]:[identifier]
<entry xmlns="http://www.w3.org/2005/Atom"

xmlns:osapi="http://opensocial.org/2008/opensocialapi">

<osapi:recipient>example.org:group:AD38B3886625AAF</osapi:recipient>

<osapi:recipient>example.org:person:997638BAA6F25AD</osapi:recipient>

<osapi:recipient>example.org:6221226</osapi:recipient>

<title>You have an invitation from Joe</title>

<id>{msgid}</id>

<link rel="alternate" href="http://app.example.org/invites/{msgid}"/>

<content>Click <a href="http://app.example.org/invites/{msgid}">here</a> to review your invitation.</content>

</entry>

The {msgid} is server generated and is globally unique. The client should use a standard AtomPub POST to /messages/{guid}/@outbox. The response is 201 Created on success.

If not supported, the response code should be 403 Not Implemented.

Typically a container would choose to only allow a POST to an outbox where the {guid} equals the requester id, but this is a container security policy decision.

Containers may choose to allow messaging only between friends or user other heuristics to prevent spam.

The 'sender' field in the message representations is only needed when receiving a message with a GET request. It is not required when POSTING a new message as this information is represented by the {guid}. Using a Person for the sender field allows a gadget to present meaningful information about the message sender without requiring a separate request for this information.

The 'data' field is used for information specific to the gadget that is sending or displaying the message. It may be omitted in most messages. An example is a message from a user asking to join a group. In the received message to the group's owner(s), the 'data' field could contain the JSON or XML representation of an OpenSocial Group.


Field Names

Each field is defined as either a Singular Field, in which case there can be at most one instance of that field per contact, or as a Plural Field, which case any number of instances of that field may be present per contact.  Unless otherwise specified, all fields are optional and of type xs:string.

Person

Each person returned MUST include the id and displayName fields with non-empty values, but all other fields are optional, and it is recognized that not all Service Providers will be able to provide data for all the supported fields. The field list is below is broad so that, for Service Providers that do support any of these fields, there is a standard field name available

singular person fields

anniversary:
The wedding anniversary of this person. The value MUST be a valid xs:date (e.g. 1975-02-14. The year value MAY be set to 0000 when the year is not available.
birthday:
The birthday of this person. The value MUST be a valid xs:date (e.g. 1975-02-14. The year value MAY be set to0000 when the age of the Person is private or the year is not available.
connected:
Boolean value indicating whether the user and this Person have established a bi-directionally asserted connection of some kind on the Service Provider's service. The value MUST be either true or false. The value MUST be true if and only if there is at least one value for the relationship field, described below, and is thus intended as a summary value indicating that some type of bi-directional relationship exists, for Consumers that aren't interested in the specific nature of that relationship. For traditional address books, in which a user stores information about other contacts without their explicit acknowledgment, or for services in which users choose to "follow" other users without requiring mutual consent, this value will always be false.
displayName:
The name of this Person, suitable for display to end-users. Each Person returned MUST include a non-emptydisplayName value. The name SHOULD be the full name of the Person being described if known (e.g. Cassandra Doll or Mrs. Cassandra Lynn Doll, Esq.), but MAY be a username or handle, if that is all that is available (e.g. doll). The value provided SHOULD be the primary textual label by which this Person is normally displayed by the Service Provider when presenting it to end-users.
gender:
The gender of this person. Service Providers SHOULD return one of the following Canonical Values, if appropriate:malefemale, or undisclosed, and MAY return a different value if it is not covered by one of these Canonical Values.
id:
Unique identifier for the Person. Each Person returned MUST include a non-empty id value. This identifier MUST be unique across this user's entire set of people, but MAY not be unique across multiple users' data. It MUST be a stable ID that does not change when the same contact is returned in subsequent requests. For instance, an e-mail address is not a good id, because the same person may use a different e-mail address in the future. Usually, in internal database ID will be the right choice here, e.g. "12345".
name:
The broken-out components and fully formatted version of the person's real name, as described in Section 11.1.3 (name Element).
nickname:
The casual way to address this Person in real life, e.g. "Bob" or "Bobby" instead of "Robert". This field SHOULD NOT be used to represent a user's username (e.g. jsmarr or daveman692); the latter should be represented by the preferredUsername field.
note:
Notes about this person, with an unspecified meaning or usage (normally notes by the user about this person). This field MAY contain newlines.
preferredUsername:
The preferred username of this person on sites that ask for a username (e.g. jsmarr or daveman692). This field may be more useful for describing the owner (i.e. the value when /@me/@self is requested) than the user's person, e.g. Consumers MAY wish to use this value to pre-populate a username for this user when signing up for a new service.
published:
The date this Person was first added to the user's address book or friends list (i.e. the creation date of this entry). The value MUST be a valid xs:dateTime (e.g. 2008-01-23T04:56:22Z).
updated:
The most recent date the details of this Persont were updated (i.e. the modified date of this entry). The value MUST be a valid xd:dateTime (e.g. 2008-01-23T04:56:22Z). If this Person has never been modified since its initial creation, the value MUST be the same as the value of published. Note the updatedSince Query Parameter can be used to select only people whose updated value is equal to or more recent than a given xs:dateTime. This enables Consumers to repeatedly access a user's data and only request newly added or updated contacts since the last access time.
utcOffset:
The offset from UTC of this Person's current time zone, as of the time this response was returned. The value MUST conform to the offset portion of xs:dateTime, e.g. -08:00. Note that this value MAY change over time due to daylight saving time, and is thus meant to signify only the current value of the user's timezone offset.

The following additional Singular Fields are defined, based on their specification in the OpenSocial javascript apis: aboutMebodyType,currentLocationdrinkerethnicityfashionhappiestWhenhumorlivingArrangementlookingForprofileSong,profileVideorelationshipStatusreligionromancescaredOfsexualOrientationsmoker, and status.


plural person fields

Unless specified otherwise, all Plural Fields have the same three standard sub-fields:

value:
The primary value of this field, e.g. the actual e-mail address, phone number, or URL. When specifying a sortByfield in the Query Parameters for a Plural Field, the default meaning is to sort based on this value sub-field. Each non-empty Plural Field value MUST contain at least the value sub-field, but all other sub-fields are optional.
type:
The type of field for this instance, usually used to label the preferred function of the given contact information. Unless otherwise specified, this string value specifies Canonical Values of workhome, and other
primary:
A Boolean value indicating whether this instance of the Plural Field is the primary or preferred value of for this field, e.g. the preferred mailing address or primary e-mail address. Service Providers MUST NOT mark more than one instance of the same Plural Field as primary="true", and MAY choose not to mark any fields as primary, if this information is not available. For efficiency, Service Providers SHOULD NOT mark all non-primary fields with primary="false", but should instead omit this sub-field for all non-primary instances.

When returning Plural Fields, Service Providers SHOULD canonicalize the value returned, if appropriate (e.g. for e-mail addresses and URLs). Providers MAY return the same value more than once with different types (e.g. the same e-mail address may used for work and home), but SHOULD NOT return the same (type, value) combination more than once per Plural Field, as this complicates processing by the Consumer.

emails:
E-mail address for this Person. The value SHOULD be canonicalized by the Service Provider, e.g.joseph@plaxo.com instead of joseph@PLAXO.COM.
urls:
URL of a web page relating to this Person. The value SHOULD be canonicalized by the Service Provider, e.g.http://josephsmarr.com/about/ instead of JOSEPHSMARR.COM/about/. In addition to the standard Canonical Values for type, this field also defines the additional Canonical Values blog and profile.
phoneNumbers:
Phone number for this Person. No canonical value is assumed here. In addition to the standard Canonical Values for type, this field also defines the additional Canonical Values mobilefax, and pager.
ims:
Instant messaging address for this Person. No official canonicalization rules exist for all instant messaging addresses, but Service Providers SHOULD remove all whitespace and convert the address to lowercase, if this is appropriate for the service this IM address is used for. Instead of the standard Canonical Values for type, this field defines the following Canonical Values to represent currently popular IM services: aimgtalkicqxmpp,msnskypeqq, and yahoo.
photos:
URL of a photo of this person. The value SHOULD be a canonicalized URL, and MUST point to an actual image file (e.g. a GIF, JPEG, or PNG image file) rather than to a web page containing an image. Service Providers MAY return the same image at different sizes, though it is recognized that no standard for describing images of various sizes currently exists. Note that this field SHOULD NOT be used to send down arbitrary photos taken by this user, but specifically profile photos of the contact suitable for display when describing the contact.
tags:
A user-defined category label for this person, e.g. "favorite" or "web20". These values SHOULD be case-insensitive, and there SHOULD NOT be multiple tags provided for a given person that differ only in case. Note that this field consists only of a string value.
relationships:
A bi-directionally asserted relationship type that was established between the user and this person by the Service Provider. The value SHOULD conform to one of the XFN relationship values (e.g. kin, friend, contact, etc.) if appropriate, but MAY be an alternative value if needed. Note this field is a parallel set of category labels to thetags field, but relationships MUST have been bi-directionally confirmed, whereas tags are asserted by the user without acknowledgment by this Person. Note that this field consists only of a string value.
addresses:
A physical mailing address for this Person, as described in Section 11.1.4 (address Element).
organizations:
A current or past organizational affiliation of this Person, as described in Section 11.1.5 (organization Element).
accounts:
An online account held by this Person, as described in Section 11.1.6 (account Element).

The following additional Plural Fields are defined, based on their specification in OpenSocial: activitiesbookscarschildren,foodheroesinterestsjobInterestslanguageslanguagesSpokenmoviesmusicpetspoliticalViewsquotessports,turnOffsturnOns, and tvShows.


name element


The components of the person's real name. Providers MAY return just the full name as a single string in the formatted sub-field, or they MAY return just the individual component fields using the other sub-fields, or they MAY return both. If both variants are returned, they SHOULD be describing the same name, with the formatted name indicating how the component fields should be combined.

formatted:
The full name, including all middle names, titles, and suffixes as appropriate, formatted for display (e.g. Mr. Joseph Robert Smarr, Esq.). This is the Primary Sub-Field for this field, for the purposes of sorting and filtering.
familyName:
The family name of this Person, or "Last Name" in most Western languages (e.g. Smarr given the full name Mr. Joseph Robert Smarr, Esq.).
givenName:
The given name of this Person, or "First Name" in most Western languages (e.g. Joseph given the full name Mr. Joseph Robert Smarr, Esq.).
middleName:
The middle name(s) of this Person (e.g. Robert given the full name Mr. Joseph Robert Smarr, Esq.).
honorificPrefix:
The honorific prefix(es) of this Person, or "Title" in most Western languages (e.g. Mr. given the full name Mr. Joseph Robert Smarr, Esq.).
honorificSuffix:
The honorifix suffix(es) of this Person, or "Suffix" in most Western languages (e.g. Esq. given the full name Mr. Joseph Robert Smarr, Esq.).

address element

The components of a physical mailing address. Service Providers MAY return just the full address as a single string in the formattedsub-field, or they MAY return just the individual component fields using the other sub-fields, or they MAY return both. If both variants are returned, they SHOULD be describing the same address, with the formatted address indicating how the component fields should be combined.

formatted:
The full mailing address, formatted for display or use with a mailing label. This field MAY contain newlines. This is the Primary Sub-Field for this field, for the purposes of sorting and filtering.
streetAddress:
The full street address component, which may include house number, street name, PO BOX, and multi-line extended street address information. This field MAY contain newlines.
locality:
The city or locality component.
region:
The state or region component.
postalCode:
The zipcode or postal code component.
country:
The country name component.
latitude:
Expresses the latitude of the location on a map.
longitude:
Expresses the longitude of the location on a map.
type:
The address type or label. Examples include 'work', 'home'.

organization element

Describes a current or past organizational affiliation of this contact. Service Providers that support only a single Company Name and Job Title field should represent them with a single organization element with name and title properties, respectively.

name:
The name of the organization (e.g. company, school, or other organization). This field MUST have a non-empty value for each organization returned. This is the Primary Sub-Field for this field, for the purposes of sorting and filtering.
department:
The department within this organization.
title:
The job title or organizational role within this organization.
type:
The type of organization, with Canonical Values job and school.
startDate:
The date this Person joined this organization. This value SHOULD be a valid xs:date if possible, but MAY be an unformatted string, since it is recognized that this field is often presented as free-text.
endDate:
The date this Person left this organization or the role specified by title within this organization. This value SHOULD be a valid xs:date if possible, but MAY be an unformatted string, since it is recognized that this field is often presented as free-text.
location:
The physical location of this organization. This may be a complete address, or an abbreviated location like "San Francisco".
description:
A textual description of the role this Person played in this organization. This field MAY contain newlines.

account element

Describes an account held by this Person, which MAY be on the Service Provider's service, or MAY be on a different service. Consumers SHOULD NOT assume that this account has been verified by the Service Provider to actually belong to this Person. For each account, the domain is the top-most authoritative domain for this account, e.g. yahoo.com or reader.google.com, and MUST be non-empty. Each account must also contain a non-empty value for either username or userid, and MAY contain both, in which case the two values MUST be for the same account. These accounts can be used to determine if a user on one service is also known to be the same person on a different service, to facilitate connecting to people the user already knows on different services. If Consumers want to turn these accounts into profile URLs, they can use an open-source library like [Social Graph Node Mapper] (Fitzpatrick, B.).

domain:
The top-most authoritative domain for this account, e.g. "twitter.com". This is the Primary Sub-Field for this field, for the purposes of sorting and filtering.
username:
An alphanumeric user name, usually chosen by the user, e.g. "jsmarr".
userid:
A user ID number, usually chosen automatically, and usually numeric but sometimes alphanumeric, e.g. "12345" or "1Z425A".


Activity

activity fields

The following fields are defined, based on their specification in the OpenSocial javascript apis: appId, body, bodyId, externalId, id, mediaItems, postedTime, priority, streamFaviconUrl, streamSourceUrl, streamTitle, streamUrl, templateParams, title, url, userId

Message

message fields

The following fields are defined, based on their specification in the OpenSocial javascript apis: type, title, body, titleId, bodyId, id, recipients, senderId, timeSent, inReplyTo, replies, status, appUrl, collectionIds, updated, urls.

XML format XSD

The response to a request with format=xml MUST conform to the following XSD: 

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://ns.opensocial.org/2008/opensocial"
  elementFormDefault="qualified"
  targetNamespace="http://ns.opensocial.org/2008/opensocial"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:simpleType name="EscapeTypeType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="HTML_ESCAPE" />
      <xs:enumeration value="NONE" />
    </xs:restriction>
  </xs:simpleType>
  <!--  this is a proposal for the OpenSocial 0.9 XSD. -->
  <xs:element name="person" type="tns:Person" />
  <xs:element name="group" type="tns:Group" />
  <xs:element name="activity" type="tns:Activity" />
  <xs:element name="appData" type="tns:Appdata" />
  <xs:element name="userPreferences" type="tns:UserPreferences" />
 
  <xs:element name="response" type="tns:Response" />
 
  <xs:element name="list.container" type="xs:anyType" />
 
  <xs:complexType name="Response">
    <xs:choice minOccurs="0" maxOccurs="unbounded" >
      <xs:element minOccurs="0" name="itemsPerPage" type="xs:int" />
      <xs:element minOccurs="0" name="startIndex" type="xs:long" />
      <xs:element minOccurs="0" name="totalResults" type="xs:long" />
      <xs:element minOccurs="0" name="isFiltered" type="xs:boolean" />
      <xs:element minOccurs="0" name="isSorted" type="xs:boolean" />
      <xs:element minOccurs="0" name="isUpdatedSince" type="xs:boolean" />
      <xs:element minOccurs="0" name="group" type="tns:Group" />
      <xs:element minOccurs="0" name="activity" type="tns:Activity" />
      <xs:element minOccurs="0" name="person" type="tns:Person" />
      <xs:element minOccurs="0" name="userPreferences" type="tns:UserPreferences" />
      <xs:element minOccurs="0"  maxOccurs="unbounded" name="entry" type="tns:Entry" />
      <!--  this is to allow responses to create to validate -->
      <xs:element minOccurs="0" name="map" type="xs:anyType" />
    </xs:choice>
  </xs:complexType>
 
  <xs:complexType name="Entry" >
    <xs:choice>
      <xs:element minOccurs="0" name="activity" type="tns:Activity" />
      <xs:element minOccurs="0" name="person" type="tns:Person" />
      <xs:element minOccurs="0" name="group" type="tns:Group" />
      <xs:element minOccurs="0" name="appData" type="tns:Appdata" />
      <xs:element minOccurs="0" name="userPreferences" type="tns:UserPreferences" />
      <xs:element minOccurs="0" name="album" type="tns:Album" />
      <xs:element minOccurs="0" name="mediaItem" type="tns:MediaItem" />
    </xs:choice>
  </xs:complexType>
 
   <xs:complexType name="BoolKeyValueArray">
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
      <xs:element minOccurs="0" name="entry" type="tns:BoolKeyValue"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="BoolKeyValue">
    <xs:all>
      <xs:element minOccurs="1" name="key" type="xs:string"/>
      <xs:element minOccurs="0" name="value" type="xs:boolean"/>
    </xs:all>
  </xs:complexType>
  <xs:complexType name="NumberKeyValue">
<xs:all>
<xs:element minOccurs="1" name="key" type="xs:string"/>
<xs:element minOccurs="0" name="value" type="xs:double"/>
</xs:all>
</xs:complexType>

  <xs:complexType name="StringKeyValueArray">
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
      <xs:element minOccurs="0" name="entry" type="tns:StringKeyValue"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="StringKeyValue">
    <xs:all>
      <xs:element minOccurs="1" name="key" type="xs:string"/>
      <xs:element minOccurs="0" name="value" type="xs:string"/>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="ArrayKeyValueArray">
    <xs:sequence minOccurs="0" maxOccurs="unbounded">
      <xs:element minOccurs="0" name="entry" type="tns:ArrayKeyValue"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ArrayKeyValue">
    <xs:all>
      <xs:element minOccurs="1" name="key" type="xs:string"/>
      <xs:element minOccurs="0" name="value" type="tns:StringEntryArray"/>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="StringEntryArray">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="entry" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="UserPreferences">
<xs:all minOccurs="0">
<xs:element minOccurs="0" name="lang" type="xs:string" />
<xs:element minOccurs="0" name="country" type="xs:string" />
<xs:element minOccurs="0" name="moduleId" type="xs:string" />
<xs:element minOccurs="0" name="arrayValues" type="tns:ArrayKeyValueArray" />
<xs:element minOccurs="0" name="boolValues" type="tns:BoolKeyValueArray" />
<xs:element minOccurs="0" name="numberValues" type="tns:NumberKeyValueArray" />
<xs:element minOccurs="0" name="stringValues" type="tns:StringKeyValueArray" />
</xs:all>
</xs:complexType>
  <xs:complexType name="Activity">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element minOccurs="0" name="appId" type="xs:string" />
      <xs:element minOccurs="0" name="body" type="xs:string" />
      <xs:element minOccurs="0" name="bodyId" type="xs:string" />
      <xs:element minOccurs="0" name="externalId" type="xs:string" />
      <xs:element minOccurs="0" name="id" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="mediaItems" type="tns:MediaItem" />
      <xs:element minOccurs="0" name="postedTime" type="xs:long" />
      <xs:element minOccurs="0" name="priority" type="xs:double" />
      <xs:element minOccurs="0" name="streamFaviconUrl" type="xs:string" />
      <xs:element minOccurs="0" name="streamSourceUrl" type="xs:string" />
      <xs:element minOccurs="0" name="streamTitle" type="xs:string" />
      <xs:element minOccurs="0" name="streamUrl" type="xs:string" />
      <xs:element minOccurs="0" name="templateParams" type="tns:ActivityTemplateParams" />
      <xs:element minOccurs="0" name="title" type="xs:string" />
      <xs:element minOccurs="0" name="titleId" type="xs:string" />
      <xs:element minOccurs="0" name="url" type="xs:string" />
      <xs:element minOccurs="0" name="userId" type="xs:string" />
    </xs:choice>
  </xs:complexType>

  <xs:complexType name="Activity">
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element minOccurs="0" name="appId" type="xs:string" />
      <xs:element minOccurs="0" name="body" type="xs:string" />
      <xs:element minOccurs="0" name="bodyId" type="xs:string" />
      <xs:element minOccurs="0" name="externalId" type="xs:string" />
      <xs:element minOccurs="0" name="id" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="mediaItems" type="tns:MediaItem" />
      <xs:element minOccurs="0" name="postedTime" type="xs:long" />
      <xs:element minOccurs="0" name="priority" type="xs:double" />
      <xs:element minOccurs="0" name="streamFaviconUrl" type="xs:string" />
      <xs:element minOccurs="0" name="streamSourceUrl" type="xs:string" />
      <xs:element minOccurs="0" name="streamTitle" type="xs:string" />
      <xs:element minOccurs="0" name="streamUrl" type="xs:string" />
      <xs:element minOccurs="0" name="templateParams" type="tns:ActivityTemplateParams" />
      <xs:element minOccurs="0" name="title" type="xs:string" />
      <xs:element minOccurs="0" name="titleId" type="xs:string" />
      <xs:element minOccurs="0" name="url" type="xs:string" />
      <xs:element minOccurs="0" name="userId" type="xs:string" />
    </xs:choice>
  </xs:complexType>
 
 
  <xs:complexType name="ActivityTemplateParams">
    <xs:all>
      <xs:element minOccurs="0" name="PersonKey" type="xs:string" />
      <xs:element minOccurs="0" name="PersonKey.DisplayName" type="xs:string" />
      <xs:element minOccurs="0" name="PersonKey.Id" type="xs:string" />
      <xs:element minOccurs="0" name="PersonKey.ProfileUrl" type="xs:string" />
      <xs:element minOccurs="0" name="person" type="tns:Person" />
    </xs:all>
  </xs:complexType>
 
  <xs:complexType name="Person">
    <xs:choice minOccurs="1" maxOccurs="unbounded">
      <xs:element minOccurs="0" name="aboutMe" type="xs:string" />
      <xs:element minOccurs="0" name="accounts" type="tns:Account"/>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="activities" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="addresses" type="tns:Address" />
      <xs:element minOccurs="0" name="age" type="xs:string"/>
      <xs:element minOccurs="0" name="anniversary" type="xs:dateTime" />
      <xs:element minOccurs="0" name="birthday" type="xs:dateTime" />
      <xs:element minOccurs="0" name="bodyType" type="tns:BodyType" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="books" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="cars" type="xs:string" />
      <xs:element minOccurs="0" name="children" type="xs:string" />
      <xs:element minOccurs="0" name="connected" type="tns:Presence" />
      <xs:element minOccurs="0" name="currentLocation" type="tns:Address" />
      <xs:element minOccurs="0" name="displayName" type="xs:string" />
      <xs:element minOccurs="0" name="drinker" type="tns:Drinker" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="emails" type="tns:PluralPersonField" />
      <xs:element minOccurs="0" name="ethnicity" type="xs:string" />
      <xs:element minOccurs="0" name="fashion" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="food" type="xs:string" />
      <xs:element minOccurs="0" name="gender" type="xs:string" />
      <xs:element minOccurs="0" name="happiestWhen" type="xs:string" />
      <xs:element minOccurs="0" name="hasApp" type="xs:boolean" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="heroes" type="xs:string" />
      <xs:element minOccurs="0" name="humor" type="xs:string" />
      <xs:element minOccurs="0" name="id" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="ims" type="tns:PluralPersonField"/>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="interests" type="xs:string" />
      <xs:element minOccurs="0" name="jobInterests" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="languagesSpoken" type="xs:string" />
      <xs:element minOccurs="0" name="livingArrangement" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="lookingFor" type="tns:LookingFor" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="movies" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="music" type="xs:string" />
      <xs:element minOccurs="0" name="name" type="tns:Name" />
      <xs:element minOccurs="0" name="networkPresence" type="tns:NetworkPresence" />
      <xs:element minOccurs="0" name="nickname" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="organizations" type="tns:Organization" />
      <xs:element minOccurs="0" name="pets" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="phoneNumbers" type="tns:PluralPersonField" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="photos" type="tns:PluralPersonField" />
      <xs:element minOccurs="0" name="politicalViews" type="xs:string" />
      <xs:element minOccurs="0" name="preferredUsername" type="xs:string" />
      <xs:element minOccurs="0" name="profileSong" type="tns:Url" />
      <xs:element minOccurs="0" name="profileUrl" type="xs:string" />
      <xs:element minOccurs="0" name="profileVideo" type="tns:Url" />
      <xs:element minOccurs="0" name="published" type="xs:dateTime"/>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="quotes" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="relationships" type="xs:string" />
      <xs:element minOccurs="0" name="relationshipStatus" type="xs:string" />
      <xs:element minOccurs="0" name="religion" type="xs:string" />
      <xs:element minOccurs="0" name="romance" type="xs:string" />
      <xs:element minOccurs="0" name="scaredOf" type="xs:string" />
      <xs:element minOccurs="0" name="sexualOrientation" type="xs:string" />
      <xs:element minOccurs="0" name="smoker" type="tns:Smoker" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="sports" type="xs:string" />
      <xs:element minOccurs="0" name="status" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="tags" type="xs:string" />
      <xs:element minOccurs="0" name="thumbnailUrl" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="turnOffs" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="turnOns" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="tvShows" type="xs:string" />
      <xs:element minOccurs="0" name="updated" type="xs:dateTime"/>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="urls" type="tns:Url" />
      <xs:element minOccurs="0" name="utcOffset" type="xs:int" />
    </xs:choice>
  </xs:complexType>
 
  <xs:complexType name="Group">
    <xs:all>
      <xs:element minOccurs="0" name="id" type="xs:string" />
      <xs:element minOccurs="0" name="title" type="xs:string" />
    </xs:all>
  </xs:complexType>
  <xs:complexType name="AppdataEntry" mixed="true">
    <xs:all>
      <xs:element minOccurs="1" name="key" type="xs:string" />
      <xs:element minOccurs="1" name="value"  type="xs:anyType" />
    </xs:all>
  </xs:complexType>
  <xs:complexType name="Appdata">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="entry" type="tns:AppdataEntry" />
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="BodyType">
    <xs:all>
      <xs:element minOccurs="0" name="build" type="xs:string" />
      <xs:element minOccurs="0" name="eyeColor" type="xs:string" />
      <xs:element minOccurs="0" name="hairColor" type="xs:string" />
      <xs:element minOccurs="0" name="height" type="xs:double" />
      <xs:element minOccurs="0" name="weight" type="xs:double" />
    </xs:all>
  </xs:complexType>
 
  <xs:complexType name="Address">
    <xs:all>
      <xs:element minOccurs="0" name="country" type="xs:string" />
      <xs:element minOccurs="0" name="extendedAddress" type="xs:string" />
      <xs:element minOccurs="0" name="latitude" type="xs:double" />
      <xs:element minOccurs="0" name="locality" type="xs:string" />
      <xs:element minOccurs="0" name="longitude" type="xs:double" />
      <xs:element minOccurs="0" name="poBox" type="xs:string" />
      <xs:element minOccurs="0" name="postalCode" type="xs:string" />
      <xs:element minOccurs="0" name="primary" type="xs:boolean"/>
      <xs:element minOccurs="0" name="region" type="xs:string" />
      <xs:element minOccurs="0" name="streetAddress" type="xs:string" />
      <xs:element minOccurs="0" name="type" type="xs:string" />
      <xs:element minOccurs="0" name="formatted" type="xs:string" />
    </xs:all>
  </xs:complexType>
 
 
  <xs:complexType name="Account">
    <xs:all>
      <xs:element minOccurs="0" name="domain" type="xs:string" />
      <xs:element minOccurs="0" name="primary" type="xs:boolean"/>
      <xs:element minOccurs="0" name="userid" type="xs:string" />
      <xs:element minOccurs="0" name="username" type="xs:string" />
    </xs:all>
  </xs:complexType>
 
 
  <xs:complexType name="Organization">
    <xs:all>
      <xs:element minOccurs="0" name="address" type="tns:Address" />
      <xs:element minOccurs="0" name="department" type="xs:string" />
      <xs:element minOccurs="0" name="description" type="xs:string" />
      <xs:element minOccurs="0" name="endDate" type="xs:dateTime" />
      <xs:element minOccurs="0" name="name" type="xs:string" />
      <xs:element minOccurs="0" name="startDate" type="xs:dateTime" />
      <xs:element minOccurs="0" name="type" type="xs:string" />
      <xs:element minOccurs="0" name="title" type="xs:string" />
      <xs:element minOccurs="0" name="field" type="xs:string" />
      <xs:element minOccurs="0" name="subField" type="xs:string" />
      <xs:element minOccurs="0" name="webpage" type="xs:string" />
      <xs:element minOccurs="0" name="salary" type="xs:string" />
  
    </xs:all>
  </xs:complexType>
  <xs:complexType name="Name">
    <xs:all>
      <xs:element minOccurs="0" name="additionalName" type="xs:string" />
      <xs:element minOccurs="0" name="familyName" type="xs:string" />
      <xs:element minOccurs="0" name="givenName" type="xs:string" />
      <xs:element minOccurs="0" name="honorificPrefix" type="xs:string" />
      <xs:element minOccurs="0" name="honorificSuffix" type="xs:string" />
      <xs:element minOccurs="0" name="formatted" type="xs:string" />
    </xs:all>
  </xs:complexType>
 
  <xs:complexType name="Url">
    <xs:all>
      <xs:element minOccurs="0" name="value" type="xs:string" />
      <xs:element minOccurs="0" name="linkText" type="xs:string" />
      <xs:element minOccurs="0" name="type" type="xs:string" />
    </xs:all>
  </xs:complexType>
 
  <xs:complexType name="Album">
    <xs:all>
      <xs:element minOccurs="0" name="id" type="xs:string" />
      <xs:element minOccurs="0" name="thumbnailUrl" type="xs:string" />
      <xs:element minOccurs="0" name="title" type="xs:string" />
      <xs:element minOccurs="0" name="description" type="xs:string" />
      <xs:element minOccurs="0" name="location" type="tns:address" />
      <xs:element minOccurs="0" name="ownerId" type="xs:string" />
      <xs:element minOccurs="0" name="mediaType" type="tns:MediaItemType" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="mediaMimeType" type="xs:string" />
      <xs:element minOccurs="0" name="mediaItemCount" type="xs:integer" />
    </xs:all>
  </xs:complexType>
  <xs:complexType name="MediaItem">
    <xs:all>
        <xs:element minOccurs="0" name="id" type="xs:string" />
        <xs:element minOccurs="0" name="title" type="xs:string" />
        <xs:element minOccurs="0" name="created" type="xs:string" />
       <xs:element minOccurs="0" name="thumbnailUrl" type="xs:string" />
      <xs:element minOccurs="0" name="description" type="xs:string" />
      <xs:element minOccurs="0" name="duration" type="xs:integer" />
      <xs:element minOccurs="0" name="location" type="tns:address" />
      <xs:element minOccurs="0" name="language" type="xs:string" />
      <xs:element minOccurs="0" name="albumId" type="xs:string" />
      <xs:element minOccurs="0" name="fileSize" type="xs:long" />
      <xs:element minOccurs="0" name="startTime" type="xs:string" />
      <xs:element minOccurs="0" name="rating" type="xs:integer" />
      <xs:element minOccurs="0" name="numVotes" type="xs:integer" />
      <xs:element minOccurs="0" name="numComments" type="xs:integer" />
      <xs:element minOccurs="0" name="numViews" type="xs:integer" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="tags" type="xs:string" />
      <xs:element minOccurs="0" maxOccurs="unbounded" name="taggedPeople" type="xs:string" />
      <xs:element minOccurs="0" name="mimeType" type="xs:string" />
      <xs:element minOccurs="0" name="type" type="tns:MediaItemType" />
      <xs:element minOccurs="0" name="url" type="xs:string" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="MediaItemType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="AUDIO" />
      <xs:enumeration value="IMAGE" />
      <xs:enumeration value="VIDEO" />
    </xs:restriction>
  </xs:simpleType>
 
 
  <xs:complexType name="Drinker">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:DrinkerType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="DrinkerType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="HEAVILY" />
      <xs:enumeration value="NO" />
      <xs:enumeration value="OCCASIONALLY" />
      <xs:enumeration value="QUIT" />
      <xs:enumeration value="QUITTING" />
      <xs:enumeration value="REGULARLY" />
      <xs:enumeration value="SOCIALLY" />
      <xs:enumeration value="YES" />
    </xs:restriction>
  </xs:simpleType>
 
 
  <xs:complexType name="Presence">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:PresenceType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="PresenceType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="AWAY" />
      <xs:enumeration value="CHAT" />
      <xs:enumeration value="DND" />
      <xs:enumeration value="OFFLINE" />
      <xs:enumeration value="ONLINE" />
      <xs:enumeration value="XA" />
    </xs:restriction>
  </xs:simpleType>
 
 
  <xs:complexType name="Smoker">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:SmokerType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="SmokerType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="HEAVILY" />
      <xs:enumeration value="NO" />
      <xs:enumeration value="OCCASIONALLY" />
      <xs:enumeration value="QUIT" />
      <xs:enumeration value="QUITTING" />
      <xs:enumeration value="REGULARLY" />
      <xs:enumeration value="SOCIALLY" />
      <xs:enumeration value="YES" />
    </xs:restriction>
  </xs:simpleType>
 
  <xs:complexType name="CreateActivityPriority">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:CreateActivityPriorityType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="CreateActivityPriorityType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="HIGH" />
      <xs:enumeration value="LOW" />
    </xs:restriction>
  </xs:simpleType>
 
  <xs:complexType name="EscapeType">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:EscapeTypeType" />
    </xs:all>
  </xs:complexType>
 

  <xs:complexType name="Message">

    <xs:all>

      <xs:element minOccurs="0" name="body" type="xs:string" />

      <xs:element minOccurs="0" name="bodyId" type="xs:string" />

      <xs:element minOccurs="0" name="title" type="xs:string" />

      <xs:element minOccurs="0" name="titleId" type="xs:string" />

      <xs:element minOccurs="0" name="id" type="xs:string" />

      <xs:element minOccurs="0" name="recipients" type="xs:string" />

      <xs:element minOccurs="0" name="senderId" type="xs:string" />

      <xs:element minOccurs="0" name="timeSent" type="xs:string" />

      <xs:element minOccurs="0" name="inReplyTo" type="xs:string" />

      <xs:element minOccurs="0" name="replies" type="xs:string" />

      <xs:element minOccurs="0" name="status" type="xs:string" />

      <xs:element minOccurs="0" name="appUrl" type="xs:string" />

      <xs:element minOccurs="0" name="collectionIds" type="xs:string" />

      <xs:element minOccurs="0" name="updated" type="xs:string" />

      <xs:element minOccurs="0" name="urls" type="xs:string" />

    </xs:all>

  </xs:complexType>


  <xs:complexType name="MessageType">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:MessageTypeType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="MessageTypeType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="EMAIL" />
      <xs:enumeration value="NOTIFICATION" />
      <xs:enumeration value="PRIVATE_MESSAGE" />
      <xs:enumeration value="PUBLIC_MESSAGE" />
    </xs:restriction>
  </xs:simpleType>
 
 
 
  <xs:complexType name="Environment">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:EnvironmentType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="EnvironmentType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ACTIVITY" />
      <xs:enumeration value="ADDRESS" />
      <xs:enumeration value="BODY_TYPE" />
      <xs:enumeration value="EMAIL" />
      <xs:enumeration value="FILTER_TYPE" />
      <xs:enumeration value="MEDIAITEM" />
      <xs:enumeration value="MESSAGE" />
      <xs:enumeration value="MESSAGE_TYPE" />
      <xs:enumeration value="NAME" />
      <xs:enumeration value="ORGANIZATION" />
      <xs:enumeration value="PERSON" />
      <xs:enumeration value="PHONE" />
      <xs:enumeration value="SORTORDER" />
      <xs:enumeration value="URL" />
    </xs:restriction>
  </xs:simpleType>
 
 
 
 
  <xs:complexType name="LookingFor">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:LookingForType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="LookingForType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="ACTIVITY_PARTNERS" />
      <xs:enumeration value="DATING" />
      <xs:enumeration value="FRIENDS" />
      <xs:enumeration value="NETWORKING" />
      <xs:enumeration value="RANDOM" />
      <xs:enumeration value="RELATIONSHIP" />
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="NetworkPresence">
    <xs:all>
      <xs:element minOccurs="0" name="displayValue" type="xs:string" />
      <xs:element minOccurs="0" name="value" type="tns:NetworkPresenceType" />
    </xs:all>
  </xs:complexType>
  <xs:simpleType name="NetworkPresenceType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="AWAY" />
      <xs:enumeration value="CHAT" />
      <xs:enumeration value="DND" />
      <xs:enumeration value="OFFLINE" />
      <xs:enumeration value="ONLINE" />
      <xs:enumeration value="XA" />
    </xs:restriction>
  </xs:simpleType>
 
  <xs:complexType name="PluralPersonField">
    <xs:all>
      <xs:element minOccurs="0" name="value" type="xs:string" />
      <xs:element minOccurs="0" name="type" type="xs:string" />
      <xs:element minOccurs="0" name="primary" type="xs:boolean"/>
    </xs:all>
  </xs:complexType>
 
 
</xs:schema>



HTTP Status Codes

Status code Description
400 BAD REQUEST OpenSocial application servers MUST return 400 BAD REQUEST under any one or more of the following conditions:
* Invalid request URI
* Invalid HTTP Header
* Receiving an unsupported, nonstandard parameter
* Receiving an invalid HTTP Message Body
401 UNAUTHORIZED OpenSocial container servers MUST return 401 UNAUTHORIZED when receiving a request for a protected resource and the request is either
* Missing OAuth authorization credentials as described in OAuth Consumer Request 1.0, http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/1/spec.html.
* OAuth authorization credentials are present, but the user identity is not authorized to access the protected resource. If the request already included authorization credentials, the 401 response indicates that the request has been refused for those credentials. A 401 response MUST include a WWW-Authenticate header field indicating the request MAY present an OAuth token for the container server's realm. Example: WWW-Authenticate: OAuth realm="http://sp.example.com/"
403 FORBIDDEN The server understood the request but is refusing to fulfill it. Authorization will not help. The current authorization context does not allow the request.
404 NOT FOUND The server has not found a resource (such as a feed or entry) that matches the request URI.
405 METHOD NOT ALLOWED The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.
409 CONFLICT The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required. Conflicts are most likely to occur in response to a PUT request. For example, this code can be used for a limit exceeded error as well as conflicting updates. See the error message for more information.
500 INTERNAL SERVER ERROR Internal error. This is the default code that is used for all unrecognized errors.
501 NOT IMPLEMENTED The request was valid but has not been implemented by the provider. A container SHOULD return 501 NOT IMPLEMENTED when receiving a request for an OPTIONAL/MAY feature that the container does not implement.

Compatibility with Portable Contacts

This version of the OpenSocial RESTful protocol specification is currently wire-compatible with the Portable Contacts version 1.0 overlapping portion of OpenSocial. Specifically, any compliant OpenSocial 0.9 People Provider is also a compliante Portable Contacts 1.0 Provider, because they are specified to use the same Authorization methods (OAuth), Additional Path Information, Query Parameters, and Contact Schema. The OpenSocial and Portable Contacts communities chose to wire-align our respective specs in order to maximize widespread adoption of a single API for accessing people data. It is our intention to maintain this compatibility going forward, so long as it is feasible, and so long as the changes required are compatible with the Goals and Approach of this spec. Although Portable Contacts is an independent spec, with a more limited scope than OpenSocial, any proposed changes to either this OpenSocial RESTful Protocol spec or the Portable Contacts spec should be considered in the context of both communities, and we should strive not to break compatibility unless it is truly necessary, e.g. if the goals of the two communities diverge significantly in the future.

Cached Content Invalidation

Containers MUST support the invalidation endpoint even if they do not perform any caching and MUST provide an entry for it in their XRDS. To invalidate content a developers backend notifies the container of the content it wishes to invalidate by making a 2-legged OAuth call to the REST/RPC endpoint with one or many keys to be invalidated. The consumer key in the 2-legged OAuth call is used by the container to identify the calling application. Keys have the following general form

<invalidation-key> = url | <opensocial id>


When invalidating opensocial id's containers MUST support invalidating both fully qualified opensocial ids of the form "<domain>:<domain relative id>" as well as ids of the form "<domain relative id>".

Each request accepts a repeated group of ids, in JSON the format is

 { invalidationKeys : [ <invalidation-key>, <invalidation-key>, ...] }

and in XML

 <invalidationKeys>

<invalidationKey>...</invalidationKey>

<invalidationKey>...</invalidationKey>

</invalidationKeys >


An application can execute an invalidation request as a POST to the REST endpoint described in the containers XRDS or as a JSON-RPC call. Response codes have the following meanings

  • 200 - Success, all invalidations processed successfully.
  • 403 - Forbidden because authentication failed.
  • 409 - The request was partially processed, the set of invalidation keys that were not honored MUST be included in the response body in the format the request was made.

Containers MAY reject invalidation requests for policy reasons. Containers MAY continue to serve content that has already been invalidated until the container is able to successfully fetch a replacement from it original source.

Examples

Invalidate the gadget spec and message bundle of an application using REST
 POST /api/rest/invalidate

HOST opensocial.example.org

Content-Type application/json

{

invalidationKeys : [ "http://www.myapp.com/gadgetpec.xml", "http://www.myapp.com/messagebundle.xml"]

}