Activity Streams/Examples
This page is for collecting concrete examples of real-world deployed Activity Stream instances.
IBM Connections
{ "startIndex": 0, "totalResults": 1, "entry": [ { "published": "2011-11-21T15:14:06.508Z", "url": "http://www.example.org/connections/opensocial/rest/activitystreams/@me/@all/@all/86c62a05-61de-4658-97a7-16e7ccf72e78", "target": { "summary": "Top App Entry", "replies": { "items": [{ "content": "This was my first comment", "author": { "objectType": "person", "id": "12345678-8f0a-1028-xxxz-db07163b51b2", "displayName": "Joe Blogs" }, "updated": "2011-11-21T15:13:59.999Z", "id": "f8f0e93f-e462-4ede-92cc-f6e8a1b7eb36" }, { "content": "This was another comment", "author": { "objectType": "person", "id": "12345678-8f0a-1028-xxxy-db07163b51b2", "displayName": "Jane Doe" }, "updated": "2011-11-21T15:14:06.508Z", "id": "5369ea82-d791-46cb-a87a-3696ff90d8f3" }], "totalItems": 0 }, "embed": { "gadget": "http://www.example.org/greatgadgets/TopApp.xml", "context": { "summary": "Test ", "topAppUrl": "http://www.example.org/topapp/atom/1028-xxxx-db07163b51b2", } }, "objectType": "note", "author": { "id": "12345678-8f0a-1028-xxxx-db07163b51b2", "displayName": "Joseph Bloggs" }, "updated": "2011-11-21T15:08:44.321Z", "id": "87d7a7fb-af22-403b-ab0d-d101d9caac4f", "displayName": "Joseph Bloggs", "published": "2011-11-21T15:08:44.321Z", "url": "http://www.example.org/topapp/1028-xxxx-db07163b51b2" }, "provider": { "id": "http://www.ibm.com/xmlns/prod/sn", "displayName": "IBM Connections - News Service", "url": "http://www.example.org/news" }, "generator": { "image": { "url": "http://www.example.org/topapp/images/icon.png" }, "id": "topapp", "displayName": "Top Application", "url": "http://www.example.org/topapp" }, "actor": { "id": "12345678-8f0a-1028-xxxx-db07163b51b2", "displayName": "Joseph Bloggs" }, "connections": { "actionable": "false", "broadcast": "true", "rollupid": "87d7a7fb-af22-403b-ab0d-d101d9caac4f", "saved": "false", "canUnFollow": "true" }, "title": "Joseph Bloggs commented on their own Top App entry.", "content": "<span class=\"vcard\"><a class=\"fn url\" title=\"This is a link to the profile of Joseph Bloggs.\" href=\"http://www.example.org/profiles/html/profileView.do?userid=12345678-8f0a-1028-xxxx-db07163b51b2\"><span class=\"photo\" src=\"http://www.example.org/profiles/photo.do?userid=12345678-8f0a-1028-xxxx-db07163b51b2\" alt=\"This is a photo of Joseph Bloggs.\" style=\"display : none\"></span>Joseph Bloggs</a><span class=\"x-lconn-userid\" style=\"display : none\">12345678-8f0a-1028-xxxx-db07163b51b2</span></span> commented on their own Top App entry.", "id": "urn:lsid:ibm.com:activitystreams:86c62a05-61de-4658-97a7-16e7ccf72e78", "updated": "2011-11-21T15:14:07.024Z", "object": { "summary": "This was my first comment", "objectType": "comment", "author": { "id": "12345678-8f0a-1028-xxxx-db07163b51b2", "displayName": "Joseph Bloggs" }, "id": "5369ea82-d791-46cb-a87a-3696ff90d8f3", "url": "http://www.example.org/topapp/1028-xxxx-db07163b51b2/comments/1" }, "verb": "post" }], "itemsPerPage": 1 }
Attributes Used
Core
- actor
- author
- content
- displayName
- entry
- generator
- id
- image
- items
- itemsPerPage
- objectType
- provider
- published
- replies
- startIndex
- summary
- target
- title
- totalResults
- updated
- url
- verb
OpenSocial extensions
- context
- embed
- gadget
- summary
- topAppUrl (connections extension?)
Connections extensions
- actionable
- broadcast
- canUnFollow
- connections
- rollupid
- saved
Additional Details
- "Templated Event Titles"
- [http://www-10.lotus.com/ldd/appdevwiki.nsf/xpAPIViewer.xsp?lookupName=IBM+Connections+5.0+API+Documentation#action=openDocument&res_title=Rendering_the_data_model_ic50&content=apicontent "Rendering the data model"
- "Connections Extensions to the Data Model"
- "Distributing events" (Audience Targeting Support)
- "Posting new events"
- "Activity Stream Search"
- "Microblog API" ... reuses parts of the AS1 model
- Other Examples
IBM Business Process Manager
{ items:[ { actor:{ displayName:"Internal TW Admin user", id:"tw_admin", objectType:"PERSON" }, content:"Internal TW Admin user completed the task titled Task: Submit requisition and associated with the Submit job requisition activity.", object:{ displayName:"Task: Submit requisition", id:"2078.3", objectType:"ibm.bpm.task" }, published:"2012-01-09T09:58:00.748-05:00", verb:"POST", replies:{ items:[ { author:{ displayName:"Internal TW Admin user", id:"tw_admin", image:{ height:32, width:32 }, objectType:"PERSON" }, content:"tagging Internal TW Admin user user", objectType:"COMMENT", published:"2012-01-09T16:18:44.743-05:00" } ] } } ], totalItems:1, more:false }
Attributes Used
Core:
- actor
- author
- content
- displayName
- height
- id (non-standard use, not an IRI)
- image
- items
- object
- objectType
- published
- replies
- totalItems
- verb
- width
Extensions:
- more (boolean)
Pump.io
https://github.com/e14n/pump.io/blob/master/API.md :
{ "id": "http://coding.example/api/activity/bwkflwken", "actor": { "id": "acct:bwk@coding.example", "objectType": "person", "displayName": "Brian Kernighan" }, "verb": "follow", "to": [{ "id": "acct:ken@coding.example", "objectType": "person" }], "object": { "id": "acct:ken@coding.example", "objectType": "person", "displayName": "Ken Thompson" }, "published": "1974-01-01T00:00:00", "links": [ {"rel": "self", "href": "http://coding.example/api/activity/bwkflwken"} ] }
Attributes Used
Core:
- actor
- displayName
- id
- object
- objectType
- published
- to
- verb
Extensions:
- links (from the original AS 2.0 Link proposal)
- rel
- href
Apigee / Apache UserGrid
Apigee uses a model that is obviously based on Activity Streams 1.0 but diverges in a number of ways.
curl -X POST "https://api.usergrid.com/my-org/my-app/users/john.doe/activities" -d '{"actor":{"displayName":"John Doe","uuid":"1f3567aa-da83-11e1-afad-12313b01d5c1","username":"john.doe", "image":{"duration":0,"height":80,"url":"http://www.gravatar.com/avatar/","width":80}, "email":"john.doe@gmail.com"},"verb":"post","content":"Hello World!"}'
{ "action" : "post", "application" : "5111c463-6a42-11e1-b6dd-1231380a0284", "params" : { }, "path" : "/users/1f3567aa-da83-11e1-afad-12313b01d5c1/activities", "uri" : "https://api.usergrid.com/5111c463-6a42-11e1-b6dd-1231380a0284/users/1f3567aa-da83-11e1-afad-12313b01d5c1/activities", "entities" : [ { "uuid" : "da448955-f3aa-11e1-8042-12313d331ae8", "type" : "activity", "created" : 1346445092974, "modified" : 1346445092974, "actor" : { "displayName" : "John Doe", "uuid" : "1f3567aa-da83-11e1-afad-12313b01d5c1", "username" : "john.doe", "image" : { "duration" : 0, "height" : 80, "url" : "http://www.gravatar.com/avatar/", "width" : 80 }, "email" : "john.doe@gmail.com" }, "content" : "Hello World!", "metadata" : { "path" : "/users/1f3567aa-da83-11e1-afad-12313b01d5c1/activities/da448955-f3aa-11e1-8042-12313d331ae8" }, "published" : 1346445092974, "verb" : "post" } ], "timestamp" : 1346445092827, "duration" : 1406, "organization": "my-org", "applicationName": "my-app" }
Livefyre
Personalized Stream Platform
Personalized Streams allow your users to create a list of Topics they wish to follow, which will then be used with the Livefyre Feed Framework, to create Apps which present them with a merged stream of updates on their selected Topics. The integration described herein allows you to enable Personalized Streams by creating and managing Topics, Subscriptions, and Collections.
- Documentation
- Sample Data (from real dataset integrator)
- Example Web Component that consumes and renders
- Activity Types
Other
Geolocation using GeoJSON
Using location property on the activity statement. Identifies where the activity took place. Does not identify location of the objects.
{ "actor": "acct:joe@example.org", "verb": "post", "object": "http://example.org", "location": { "objectType": "http://ld.geojson.org/vocab#Point", "coordinates": [36.7468420,-119.7725870] } }
Using location property on the object. Identifies the location of the object. Does not identify location where the activity took place.
{ "actor": "acct:joe@example.org", "verb": "post", "object": { "id": "http://example.org", "location": { "objectType": "http://ld.geojson.org/vocab#Point", "coordinates": [36.7468420,-119.7725870] } } }
Using location property on the actor. Identifies the location of the actor. Does not identify location where the activity took place or location of the object.
{ "actor": { "id": "acct:joe@example.org", "location": { "objectType": "http://ld.geojson.org/vocab#Point", "coordinates": [36.7468420,-119.7725870] } }, "verb": "post", "object": "http://example.org" }
Examples of Alternative Approaches
Schema.org Actions
The [Schema.org] Actions model is an alternative mechanism for describing Activity that is derived from Activity Streams but based around the Schema.org model.
Example from the schema.org Actions doc:
{ "@context": "http://schema.org", "@type": "WatchAction", "actionStatus": "CompletedActionStatus", "agent" : { "@type": "Person", "name": "Kevin Bacon" }, "object" : { "@type": "Movie", "name": "Footloose" }, "startTime" : "2014-03-01" }
The equivalent Activity Streams 2.0 markup would be:
{ "verb": "http://schema.org/WatchAction", "status": "completed", "actor": { "objectType": "http://schema.org/Person", "displayName": "Kevin Bacon" }, "object": { "objectType": "http://schema.org/Movie", "displayName": "Footloose" }, "startTime": "2014-03-01" }
Using the JSON-LD processing option we can easily bridge these two alternatives in order to allow them to be processed as equivalent (see http://www.chmod777self.com/2014/04/activity-streams-20-and-schemaorgactions.html)
The schema.org Actions model also includes a potentialActions property that serves the same basic purpose as the AS2 actions property... For instance:
{ "@context": "http://schema.org", "@type": "Movie", "name": "Footloose", "potentialAction" : { "@type": "WatchAction", "target" : "http://example.com/player?id=123" } }
Is equivalent to:
{ "objectType": "http://schema.org/Movie", "displayName": "Footloose", "actions": { "http://schema.org/WatchAction": "http://example.org/player?id=123" } }
Or even just:
{ "objectType": "http://schema.org/Movie", "displayName": "Footloose", "actions": { "watch": "http://example.org/player?id=123" } }
Facebook Actions
Facebook uses an entirely different model for Actions. See https://developers.facebook.com/docs/opengraph/using-actions/v2.0
For instance, where Activity Streams would encode an Activity that has occurred as a JSON document, the Facebook Graph API 2.0 uses HTTP POSTs, where the Request URI identifies the verb and either query string parameters or form parameters are used to describe the detail of the activity that has occurred:
POST /v2.0/me/cookbook:eat? recipe=http://www.example.com/recipes/pizza/& place=http://www.example.com/places/123/& tags=AaIin1Z1gboQUmN4C3rIz3mdChaYV& message=You should really try this recipe @[AaJfY_M0tTe_ZAM6P71Zr72msCJYG2EePwuyB] and @[AaK98FO-HdEWvGFwMLp0wzHlkzbng1PrcY]& access_token=VALID_ACCESS_TOKEN
An equivalent AS2 example would be:
POST /some/endpoint HTTP/1.1 Content-Type: application/activity+json { "actor": "urn:social:self", "verb": "eat", "object": { "objectType": "recipe", "id": "http://www.example.com/recipes/pizza" }, "location": "http://www.example.com/places/123", "content": "You should really try this recipe @[AaJfY_M0tTe_ZAM6P71Zr72msCJYG2EePwuyB] and @[AaK98FO-HdEWvGFwMLp0wzHlkzbng1PrcY]" }
Note that the Facebook API includes built-in, in-line social tagging that currently does not exist in any standard way in Activity Streams or any other open proposal. A proposal around Federated In-Line Tagging would be helpful.
Google+ Moments
While it's not clear how extensively the Google+ Moments API (see https://developers.google.com/+/api/latest/moments#resource) is being used, it does implement another alternative of reporting Activities.
Example from the Moments API docs:
{ "kind": "plus#moment", "type": string, "object": { "kind": "plus#itemScope", "type": string, "id": string, "description": string, "image": string, "name": string, "url": string, "author": [ (ItemScope) ], "contributor": [ (ItemScope) ], "dateCreated": string, "dateModified": string, "datePublished": string, "associated_media": [ (ItemScope) ], "thumbnailUrl": string, "about": (ItemScope), "contentSize": string, "contentUrl": string, "duration": string, "embedUrl": string, "height": string, "playerType": string, "width": string, "thumbnail": (ItemScope), "caption": string, "startDate": string, "endDate": string, "attendees": [ (ItemScope) ], "attendeeCount": integer, "location": (ItemScope), "performers": [ (ItemScope) ], "tickerSymbol": string, "additionalName": [ string ], "birthDate": string, "familyName": string, "gender": string, "givenName": string, "text": string, "reviewRating": (ItemScope), "ratingValue": string, "bestRating": string, "worstRating": string, "address": (ItemScope), "addressCountry": string, "addressLocality": string, "addressRegion": string, "postOfficeBoxNumber": string, "postalCode": string, "streetAddress": string, "geo": (ItemScope), "latitude": double, "longitude": double, "inAlbum": (ItemScope), "audio": (ItemScope), "byArtist": (ItemScope), "partOfTVSeries": (ItemScope) }, "result": { "kind": "plus#itemScope", "type": string, "id": string, "description": string, "image": string, "name": string, "url": string, "author": [ (ItemScope) ], "contributor": [ (ItemScope) ], "dateCreated": string, "dateModified": string, "datePublished": string, "associated_media": [ (ItemScope) ], "thumbnailUrl": string, "about": (ItemScope), "contentSize": string, "contentUrl": string, "duration": string, "embedUrl": string, "height": string, "playerType": string, "width": string, "thumbnail": (ItemScope), "caption": string, "startDate": string, "endDate": string, "attendees": [ (ItemScope) ], "attendeeCount": integer, "location": (ItemScope), "performers": [ (ItemScope) ], "tickerSymbol": string, "additionalName": [ string ], "birthDate": string, "familyName": string, "gender": string, "givenName": string, "text": string, "reviewRating": (ItemScope), "ratingValue": string, "bestRating": string, "worstRating": string, "address": (ItemScope), "addressCountry": string, "addressLocality": string, "addressRegion": string, "postOfficeBoxNumber": string, "postalCode": string, "streetAddress": string, "geo": (ItemScope), "latitude": double, "longitude": double, "inAlbum": (ItemScope), "audio": (ItemScope), "byArtist": (ItemScope), "partOfTVSeries": (ItemScope) }, "startDate": datetime, "id": string }
The structure is modeled somewhat after the Activity Streams-derived model used by other parts of the Google+ API but (oddly) chooses to break compatibility and consistency. It's not clear if this API is going to be supported long term given the evolving schema.org/Action model
Yammer API
Microsoft's Yammer API uses a JSON-based model that is very similar to Activity Streams but differs in a number of important ways. See https://developer.yammer.com/introduction/#gs-writedata
Example from the Yammer documentation:
{ "activity":{ "actor":{ "name":"Sidd Singh", "email":"sidd@xyz.com"}, "action":"create", "object": { "url":"https://www.sched.do", "title":"Lunch Meeting" }, "message":"Hey, let’s get sushi!", "users":[ {"name":"Adarsh Pandit", "email":"adarsh@xyz.com"} ] } }
Twitter Cards
Twitter Cards are less about Activity Streams and more about embedded Actions and metadata, but they are relevant examples for the discussion. See https://dev.twitter.com/docs/cards
For example, an "App Card" allows a webpage to tell Twitter about links to a native application associated with the page:
<meta name="twitter:card" content="app"> <meta name="twitter:description" content="The perfect for grabbing a nearby taxi. Try it by downloading today."> <meta name="twitter:app:country" content="US"> <meta name="twitter:app:name:iphone" content="Example App"> <meta name="twitter:app:id:iphone" content="306934135"> <meta name="twitter:app:url:iphone" content="example://action/5149e249222f9e600a7540ef"> <meta name="twitter:app:name:ipad" content="Example App"> <meta name="twitter:app:id:ipad" content="306934135"> <meta name="twitter:app:url:ipad" content="example://action/5149e249222f9e600a7540ef"> <meta name="twitter:app:name:googleplay" content="Example App"> <meta name="twitter:app:id:googleplay" content="com.example.app"> <meta name="twitter:app:url:googleplay" content="http://example.com/action/5149e249222f9e600a7540ef">
An equivalent example using Activity Streams 2.0 actions would be:
<script type="application/activity+json"> { "objectType": "application", "summary": "The perfect application for grabbing a nearby taxi." "country": "US", "actions": { "install": [ { "displayName": "Example App", "platform": "ios", "id": "example://action/5149e249222f9e600a7540ef" }, { "displayName": "Example App", "platform": "android", "id": "http://example.com/action/5149e249222f9e600a7540ef" } ] } } </script>
Github API
Github has an Event API documented here: https://developer.github.com/v3/activity/events/
It uses their own JSON based format:
[ { "type": "Event", "public": true, "payload": { }, "repo": { "id": 3, "name": "octocat/Hello-World", "url": "https://api.github.com/repos/octocat/Hello-World" }, "actor": { "id": 1, "login": "octocat", "gravatar_id": "somehexcode", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "url": "https://api.github.com/users/octocat" }, "org": { "id": 1, "login": "github", "gravatar_id": "somehexcode", "url": "https://api.github.com/orgs/github", "avatar_url": "https://github.com/images/error/octocat_happy.gif" }, "created_at": "2011-09-06T17:26:27Z", "id": "12345" } ]
The "payload" of a Github event varies depending on the event type. The supported event types are documented here: https://developer.github.com/v3/activity/events/types/
For example, a "CommitMessage" event would look something like:
{ "comment": { "url": "https://api.github.com/repos/baxterthehacker/public-repo/comments/7155476", "html_url": "https://github.com/baxterthehacker/public-repo/commit/7b80eb100206a56523dbda6202d8e5daa05e265b#commitcomment-7155476", "id": 7155476, "user": { "login": "baxterthehacker", "id": 6752317, "avatar_url": "https://avatars.githubusercontent.com/u/6752317?", "gravatar_id": "258ae60b5512c8402b93673b7478d9c6", "url": "https://api.github.com/users/baxterthehacker", "html_url": "https://github.com/baxterthehacker", "followers_url": "https://api.github.com/users/baxterthehacker/followers", "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", "repos_url": "https://api.github.com/users/baxterthehacker/repos", "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", "type": "User", "site_admin": false }, "position": null, "line": null, "path": null, "commit_id": "7b80eb100206a56523dbda6202d8e5daa05e265b", "created_at": "2014-07-25T16:37:43Z", "updated_at": "2014-07-25T16:37:43Z", "body": "This is a really good change! :+1:" }, "repository": { "id": 20000106, "name": "public-repo", "full_name": "baxterthehacker/public-repo", "owner": { "login": "baxterthehacker", "id": 6752317, "avatar_url": "https://avatars.githubusercontent.com/u/6752317?", "gravatar_id": "258ae60b5512c8402b93673b7478d9c6", "url": "https://api.github.com/users/baxterthehacker", "html_url": "https://github.com/baxterthehacker", "followers_url": "https://api.github.com/users/baxterthehacker/followers", "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", "repos_url": "https://api.github.com/users/baxterthehacker/repos", "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/baxterthehacker/public-repo", "description": "", "fork": false, "url": "https://api.github.com/repos/baxterthehacker/public-repo", "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments/{number}", "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", "created_at": "2014-05-20T22:39:43Z", "updated_at": "2014-07-25T16:37:43Z", "pushed_at": "2014-07-25T16:37:42Z", "git_url": "git://github.com/baxterthehacker/public-repo.git", "ssh_url": "git@github.com:baxterthehacker/public-repo.git", "clone_url": "https://github.com/baxterthehacker/public-repo.git", "svn_url": "https://github.com/baxterthehacker/public-repo", "homepage": null, "size": 612, "stargazers_count": 0, "watchers_count": 0, "language": null, "has_issues": true, "has_downloads": true, "has_wiki": true, "forks_count": 1, "mirror_url": null, "open_issues_count": 25, "forks": 1, "open_issues": 25, "watchers": 0, "default_branch": "master" }, "sender": { "login": "baxterthehacker", "id": 6752317, "avatar_url": "https://avatars.githubusercontent.com/u/6752317?", "gravatar_id": "258ae60b5512c8402b93673b7478d9c6", "url": "https://api.github.com/users/baxterthehacker", "html_url": "https://github.com/baxterthehacker", "followers_url": "https://api.github.com/users/baxterthehacker/followers", "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", "repos_url": "https://api.github.com/users/baxterthehacker/repos", "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", "type": "User", "site_admin": false } }
Note that the payload properties are very github centric in naming but there are common themes: "sender", "id", links to other resources, timestamps, etc.
It's worthwhile noting that Github's HTML pages include both Twitter and Facebook "card" metadata. For instance:
<meta content="@github" name="twitter:site" /> <meta content="summary" name="twitter:card" /> <meta content="jasnell/w3c-socialwg-activitystreams" name="twitter:title" /> <meta content="w3c-socialwg-activitystreams - Activity Streams 2.0 Editor Drafts" name="twitter:description" /> <meta content="https://avatars2.githubusercontent.com/u/439929?v=2&s=400" name="twitter:image:src" /> <meta content="GitHub" property="og:site_name" /> <meta content="object" property="og:type" /> <meta content="https://avatars2.githubusercontent.com/u/439929?v=2&s=400" property="og:image" /> <meta content="jasnell/w3c-socialwg-activitystreams" property="og:title" /> <meta content="https://github.com/jasnell/w3c-socialwg-activitystreams" property="og:url" /> <meta content="w3c-socialwg-activitystreams - Activity Streams 2.0 Editor Drafts" property="og:description" />
Note the duplication of content this requires. Note also that this approach forces Github to target specific ecosystems. An alternative AS 2.0 based model could look like:
<script type="application/activity+json"> { "title": "jasnell/w3c-socialwg-activitystream", "summary": "w3c-socialwg-activitystreams - Activity Streams 2.0 Editor Drafts", "image": "https://avatars2.githubusercontent.com/u/439929?v=2&s=400", "location": { "displayName": "GitHub", "objectType": "website" } } </script>
Pinterest provides another example of a domain-specific JSON-based REST API that ends up requiring the use of multiple vocabulary options. For instance, the [Rich Pin] mechanism can leverage the non-standardized oEmbed convention, Facebook's OpenGraph, or Schema.org properties.
For example, if using oEmbed, Pinterest supports doing an HTTP GET to fetch something like the following:
{ "provider_name": "FAMSF", "url": "http://shop.famsf.org/do/product/BK5160", "title": "de Young Copper Bookmark", "description": "Our signature bookmark derived from the de Young's unique architecture and copper exterior. Measures 5 3/4'' x 1 1/4''. FAMSF Exclusive.", "product_id": "BK5160", "price": 15.00, "currency_code": "USD", "availability": "in stock", "standard_price": 20.00, "sale_start_date": 2013-12-20T00:00:00, "sale_end_date": 2013-12-31T00:00:00 "gender": "unisex", "images": ["http://shop.famsf.org/storeImages/images/store/CPG-RP_l.jpg", "http://shop.famsf.org/storeImages/images/store/CPG-RP_02_l.jpg"] "rating": 4.0, "rating_scale": 5, "rating_count": 112, "related_items":["http://shop.famsf.org/Product.do?code=CPG-RP", "http://shop.famsf.org/Product.do?code=HW1S01"], "color":[{"name": "Aqua", "http://shop.famsf.org/storeImages/images/store/CPG-RP_l.jpg", "map": "blue"}, {"name": "amber", "http://shop.famsf.org/storeImages/images/store/CPG-RP_02_l.jpg", "map": "orange"}] }
An alternative schema.org based example would look something like:
<meta property="og:site_name" content="FAMSF Store" /> <div itemscope itemtype="http://schema.org/Product"> <meta itemprop="name" content="de Young Copper Bookmark" /> <meta itemprop="url" content="http://shop.famsf.org/do/product/BK5160" /> <meta itemprop="image" content="http://shop.famsf.org/images/111111.jpg" /> <meta itemprop="image" content="http://shop.famsf.org/images/222222.jpg" /> <span itemprop="description">Our signature bookmark derived from the de Young's unique architecture and copper exterior. Measures 5 3/4'' x 1 1/4''. FAMSF Exclusive.</span> <div itemprop="color" itemscope itemtype="http://schema.org/ProductColor"> <span itemprop="name">Aqua</span> <meta itemprop="map" content="blue" /> <meta itemprop="image" content="http://cdn-i3.farfetch.com/B.jpg" /> </div> <div itemprop="color" itemscope itemtype="http://schema.org/ProductColor"> <span itemprop="name">Rose</span> <meta itemprop="map" content="red" /> <meta itemprop="image" content="http://cdn-i3.farfetch.com/B.jpg" /> </div> <a itemprop="relatedItem" href="http://shop.famsf.org/do/product/444444"></a> <a itemprop="relatedItem" href="http://shop.famsf.org/do/product/222222"></a> <a itemprop="relatedItem" href="http://shop.famsf.org/do/product/333333"></a> <div itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <span itemprop="price">$15.00</span> <meta itemprop="priceCurrency" content="USD" /> <meta itemprop="availability" itemtype="http://schema.org/ItemAvailability" content="http://schema.org/InStock" /> </div> </div>
Note that while oEmbed is apparently used by a broad range of [sites], oEmbed has no known published patent or copyright license and the provenance of the specification is undocumented.