The OpenSocial Activities data API allows client applications to publish and view information about users' activities, in the form of entries in AtomPub APIs with a Google data schema. Your client application can create and publish new entries, edit or delete existing entries, or request a list of entries.
Important: The OpenSocial Activities data API hasn't been released yet; this document is a preview of the developer's guide that we'll publish when we release the data API. All of the details are subject to change, but this preview should give you a general idea of what the API will be like.
This document is intended for programmers who want to write client applications that can interact with any of Google's services that keep track of user activities, such as the "Updates from your friends" list at Orkut.
An Activities service is sometimes called a "domain"; in the URLs shown in this document, we use the placeholder term domain to indicate the part of the URL that varies from one service to another.
This document provides a series of examples of basic data API interactions using raw XML and HTTP, with explanations.
This document is intended for two different (though overlapping) groups of client developers. Both groups should read the whole document, but depending on your goal, you should focus on different parts of it:
This document assumes that you understand the general ideas behind AtomPub and the Google data APIs protocol.
An entry in an Activities feed represents an activity performed by a user. An entry specifies a user and a source, plus textual information and metadata about the event.
The user is the person who performed the activity; the source is the service that informed the Activities server that the activity had happened.
For example, a particular entry (posted to the feed by YouTube) might indicate that user liz@gmail.com uploaded a video file on YouTube. Here, liz@gmail.com is the user whose activity is being reported, and YouTube is the source of the activity. The fact that the activity consisted of uploading a video is given in the textual description.
The Google GUIs that display lists of activities are labeled as various kinds of "updates," such as "Updates from your friends." (Users can use those lists to view realtime updates showing their friends' activities on various sites across the web.) Therefore, if your client displays activities to your users, you should use the term "updates" in your GUI, rather than "activities." Note that an "update" in this sense is not the same as updating data by sending an HTTP PUT request.
To post user activities to the OpenSocial Activities API, you first need to register your application with Google.
Clients posting activities to any of Google's Activities services must abide by the following policies:
To read from or write to a feed, your client needs to authenticate. It can authenticate using either of two approaches: AuthSub proxy authentication or ClientLogin username/password authentication.
For more information about authentication with Google data APIs in general, please see the authentication documentation.
AuthSub proxy authentication is used by web applications that need to authenticate their users to Google accounts. The website operator and the client code don't have access to the username and password for the Activities user; instead, the client obtains special AuthSub tokens that allow the client to act on a particular user's behalf. See the AuthSub documentation for more detailed information.
When a user first visits your application, they have not yet been authenticated. In this case, you need to display some information and a link directing the user to a Google page to authenticate your request for access to their activities.
The AuthSubRequest URL might look like this:
https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fdomain%2Factivities%2Ffeeds%2F&session=1&secure=0&next=http%3A%2F%2Fwww.example.com%2Fwelcome.html
The following query parameters are included in the AuthSubRequest URL:
http://domain/activities/feeds.After the user logs in, the AuthSub system redirects them to the URL you specified in the next query parameter of the AuthSubRequest URL. The AuthSub system appends an authentication token to that URL, as the value of the token query parameter. For example:
http://www.example.com/welcome.html?token=yourAuthToken
This token value represents a single-use AuthSub token. In this example, since session=1 was specified, this token can be exchanged for an AuthSub session token by calling the AuthSubSessionToken service with the single-use token in an Authorization header, as follows, where urlFromAuthSub is the URL that AuthSub appended the token to:
GET /accounts/AuthSubSessionToken HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="yourAuthToken"
User-Agent: Java/1.5.0_06
Host: https://www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
The AuthSubSessionToken service response includes a Token header that contains the session token and an Expiration header that indicates how long the token will remain valid. Your application can use the session token value in the Authorization header of subsequent interactions with Activities. Here's an example of an HTTP request, containing a non-secure token, that you might send to Activities:
GET feedURL HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token="yourSessionToken"
User-Agent: Java/1.5.0_06
Host: ActivitiesServerURL
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Use ClientLogin authentication if your client is a standalone, single-user "installed" client (such as a desktop application). To request an authentication token using the ClientLogin mechanism, send a POST request to the following URL:
https://www.google.com/accounts/ClientLogin
The POST body should contain a set of query parameters that look like parameters passed by an HTML form, using the application/x-www-form-urlencoded content type. These parameters are:
exampleCo-exampleApp-1.reader. (Other service names are listed in the Google data API knowledge base.)If the authentication request fails, you'll receive an HTTP 403 Forbidden status code.
If it succeeds, then the response from the service is an HTTP 200 OK status code, plus three long alphanumeric codes in the body of the response: SID, LSID, and Auth. The Auth value is the authorization token that you'll send to Activities with your request, so keep a copy of that value. You can ignore the SID and LSID values.
Since all requests to private feeds require authentication, you have to set the Authorization header in all subsequent interactions with Activities, using the following format:
Authorization: GoogleLogin auth=yourAuthToken
Where yourAuthToken is the Auth string returned by the ClientLogin request.
For more information about ClientLogin authentication, including sample requests and responses, see the Account Authentication for Installed Applications documentation.
After successful authentication, your client can post entries describing user activities. However, a client can post only to a source-level feed, not to a user-level feed. For information about the types of feeds, see the Retrieving entries section of this document.
To post, first create an XML representation of the entry to publish. This XML needs to be in the form of an Atom <entry> element, which might look something like this:
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom'>
<atom:updated>2007-10-27T19:41: 51.574Z</atom:updated>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/activities/2007#activities'/>
<atom:title>Liz uploaded "My Date With Darcy" to YouTube.com</atom:title>
</atom:entry>
To publish this activity, send it to the feed's post URL as follows. First, place your Atom <entry> element in the body of a new POST request, using the application/atom+xml content type. Then send the request to the feed's post URL, which is in this format:
http://domain/activities/feeds/activities/user/userID/source/sourceID
The Activities server creates an entry using the data you sent, assigning the specified user and source to the activity; then it returns an HTTP 201 CREATED status code, along with a copy of the new post in the form of an <entry> element. The activity returned is the same one you sent, but it also contains various elements added by the Activities server, such as an <id> element.
If your request fails for some reason, the server may return a different status code. For information about the status codes, see the protocol reference document.
To retrieve a list of activities, your client requests an Activities feed by sending an HTTP GET request. The Activities server then returns a feed containing the appropriate activities.
There are two different kinds of feeds: user-level feeds, listing the activities associated with a specified user, and source-level feeds, listing the subset of a given user's activities that are associated with a specified source. Both contain the same kind of entries, where each entry describes an activity by a user.
To get a user-level feed, listing all the activities associated with a particular user, you send the following HTTP request to the Activities server (with the appropriate values in place of domain and userID, of course):
GET http://domain/activities/feeds/activities/user/userID
The server then returns an HTTP 200 OK status code and a standard Atom 1.0 feed containing all the activities. The following is an example of a feed with only one activity. Note that we've slightly edited the following example to make it a little more readable by humans; in particular, a real Activities feed contains actual IDs and URLs.
<atom:feed xmlns:atom='http://www.w3.org/2005/Atom'
xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
xmlns:gact='http://schemas.google.com/activities/2007'>
<atom:id>http://www.google.com/activities/feeds/activities/user/userID/source/sourceID</atom:id>
<atom:updated>1970-01-01T00:00:00.000Z</atom:updated>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/activities/2007#activity'/>
<atom:title>Feed title</atom:title>
<atom:link rel='alternate' type='text/html' href='http://sourceID.com/123'/>
<atom:link rel='http://schemas.google.com/g/2005#feed'
type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID'/>
<atom:link rel='http://schemas.google.com/g/2005#post'
type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID'/>
<atom:link rel='self' type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID'/>
<atom:author>
<atom:name>unknown</atom:name>
</atom:author>
<openSearch:totalResults>1</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>25</openSearch:itemsPerPage>
<atom:entry>
<atom:id>http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1</atom:id>
<atom:updated>2007-10-27T19:41:51.574Z</atom:updated>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/activities/2007#activity'/>
<atom:title>Activity title</atom:title>
<atom:link rel='self' type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
<atom:link rel='edit' type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
<gact:received>2007-10-27T19:41:51.478Z</gact:received>
</atom:entry>
</atom:feed>
Also note that the entry doesn't contain XML elements that specifically represent a user or a source; your client can determine the user and source by examining the <link rel="self"> element.
A source-level feed lists all the activities associated with a particular source and a particular user.
Retrieving a source-level feed is the same as retrieving a user-level feed, except that you specify a source as well as a user in the feed URL:
GET http://domain/activities/feeds/activities/user/userID/source/sourceID
A client can modify an entry only in a source-level feed.
To edit an existing entry, first retrieve the entry, then modify it, then send a PUT request with the modified entry in the message body to the entry's edit URL.
Be sure that the <id> value in the entry you POST exactly matches the <id> of the existing entry.
The edit URL is highlighted in the following entry:
<atom:entry>
<atom:id>http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1</atom:id>
<atom:updated>2007-10-27T19:41:51.574Z</atom:updated>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/activities/2007#activity'/>
<atom:title>Edited title</atom:title>
<atom:link rel='self' type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
<atom:link rel='edit' type='application/atom+xml'
href='http://www.google.com/activities/feeds/activities/user/userID/source/sourceID/a1'/>
<gact:received>2007-10-27T19:41:51.478Z</gact:received>
</atom:entry>
Note: To ensure forward compatibility, be sure that when you PUT an updated entry you preserve all the XML that was present when you retrieved the entry from the server. Otherwise, when we implement new stuff and include <new-awesome-feature> elements in the feed, your client won't return them when updating, and your users will miss out!
Troubleshooting Tip: Some firewalls block HTTP PUT messages. To get around this you can include the X-HTTP-Method-Override: PUT header in your requests.
A client can delete an entry only in a source-level feed.
To delete an activity, send a DELETE request to the activity's edit URL. This is the same URL used to update entries.
Troubleshooting Tip: Some firewalls block HTTP DELETE messages. To get around this you can include the X-HTTP-Method-Override: DELETE header in your requests.