A user is the central object utilized by the App.net Stream API. They have usernames, follow other users, and post content for their followers.
{
"id": "1", // note this is a string
"username": "mthurman",
"name": "Mark Thurman",
"description": {
"text": "Hi, I'm Mark Thurman and I'm teaching you about the @appdotnet Stream #API.",
"html": "Hi, I'm Mark Thurman and I'm <a href=\"https://github.com/appdotnet/api_spec\" rel=\"nofollow\">teaching you</a> about the <span itemprop=\"mention\" data-mention-name=\"appdotnet\" data-mention-id=\"3\">@appdotnet</span> Stream #<span itemprop=\"hashtag\" data-hashtag-name=\"api\">API</span>.",
"entities": {
"mentions": [{
"name": "appdotnet",
"id": "3",
"indices": [52, 62]
}],
"hashtags": [{
"name": "api",
"indices": [70, 74]
}],
"links": [{
"text": "teaching you",
"url": "https://github.com/appdotnet/api-spec"
"indices": [29, 41],
}]
}
},
"timezone": "US/Pacific",
"locale": "en_US",
"avatar_image": {
"height": 512,
"width": 512,
"url": "https://example.com/avatar_image.jpg"
},
"cover_image": {
"height": 118,
"width": 320,
"url": "https://example.com/cover_image.jpg"
},
"type": "human",
"created_at": "2012-07-16T17:23:34Z",
"counts": {
"follows": 100,
"followed_by": 200,
"posts": 24
},
"app_data": {
"appdotnet": {...},
"rdio": {...}
},
}
Field | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id |
string | Primary identifier for a post. Alphanumeric, always expressed as a string. This idspace is unique to Post objects. There can be a Post and User with the same ID; no relation is implied. | ||||||||||||
username |
string | Case insensitive. 20 characters, may only contain a-z, 0-9 and underscore. | ||||||||||||
name |
string | User supplied descriptive name. May be a pseudonym. All Unicode characters allowed. Maximum length N characters. | ||||||||||||
description |
object |
|
||||||||||||
timezone |
string | User timezone in tzinfo format. | ||||||||||||
locale |
string | User locale in ISO format. | ||||||||||||
avatar_image |
image object | Object representing the URL and original size of the user's avatar. | ||||||||||||
cover_image |
image object | Object representing the URL and original size of the user's over image. | ||||||||||||
type |
string | An account can be one of the following types: human , bot , corporate , or feed . |
||||||||||||
created_at |
string | The time at which the User was created in ISO 8601 format. | ||||||||||||
counts |
object |
|
||||||||||||
app_data |
object | Object where each app can store opaque information for this user. This could be useful for storing application state (read pointers, default filters in the app, etc). |
Images are objects so that app developers can more easily pick the appropriated sized image for different contexts.
{
"height": 512,
"width": 512,
"url": "https://example.com/image.jpg"
}
Images may be dynamically resized on the server by adding w
and/or h
parameters to the query string of the URL as desired. If
one of the parameters is omitted, the omitted dimension will be scaled according to the aspect ratio of the original image. Images
will be returned with HTTPS URLs, but can be fetched over HTTP if desired.
A Post is the other central object utilized by the App.net Stream API. It has rich text and annotations which comprise all of the content a users sees in their feed.
{
"id": "1", // note this is a string
"user": {
...
},
"created_at": "2012-07-16T17:25:47Z",
"text": "@berg FIRST post on this new site #newsocialnetwork",
"html": "<span itemprop=\"mention\" data-mention-name=\"berg\" data-mention-id=\"2\">@berg</span> FIRST post on <a href=\"https://join.app.net\" rel=\"nofollow\">this new site</a> <span itemprop=\"hashtag\" data-hashtag-name=\"newsocialnetwork\">#newsocialnetwork</span>.",
"source": {
"name": "Clientastic for iOS",
"link": "http://app.net"
},
"reply_to": null,
"annotations": {
"wellknown:geo": {
"type": "Point",
"coordinates": [102.0, .5]
}
},
"entities": {
"mentions": [{
"name": "berg",
"id": "2",
"indices": [0, 4]
}],
"hashtags": [{
"name": "newsocialnetwork",
"indices": [34, 50]
}],
"links": [{
"text": "this new site",
"url": "https://join.app.net"
"indices": [20, 32],
}]
}
}
Field | Type | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
id |
string | Always present. | |||||||||
user |
object | This is an embedded version of the User object. | |||||||||
created_at |
string | The time at which the post was create in ISO 8601 format. | |||||||||
text |
string | User supplied text of the post. | |||||||||
html |
string | Server-generated annotated HTML rendering of post text. | |||||||||
source |
object |
|
|||||||||
reply_to |
string | The id of the post this post is replying to (or null if not a reply). |
|||||||||
annotations |
object | Metadata about the entire post. See the annotations documentation. | |||||||||
entities |
object | Rich text information for this post. See the entities documentation. |
- TODOs
- Reply model
Post annotations are attributes (key, value pairs) that describe the entire post. There will be globally defined annotation formats (like geo above) but each application can also define annotations in their own namespace (like the Rdio song).
TODO
Entities allow users and applications to provide rich text formatting for posts. They provide common formatting for mentions and hashtags but they also allow links to be embedded with anchor text which gives more context. Each entity type is a list with 0 or more entities of the same type.
Entities are designed to be very simple to render — they should relatively easily translate into NSAttributedString
objects and the like.
Ranges specified by entities may be adjacent, but may not overlap.
All of the following examples are about the following post:
@berg FIRST post on this new site #newsocialnetwork
Bring another user's attention to your post. A mention starts with @
.
"mentions": [{
"name": "berg",
"id": "2",
"indices": [0, 4]
}]
Field | Type | Description |
---|---|---|
name |
string | The username being mentioned (doesn't include '@'). |
id |
string | The user id of the mentioned user. |
indices |
list | A 2 element long list which represents what subset of the text is formatted (include @). |
Tag a post about a specific subject. A hashtag starts with #
.
"hashtags": [{
"name": "newsocialnetwork",
"indices": [34, 50]
}]
Field | Type | Description |
---|---|---|
name |
string | The text of the hashtag (not including #). |
indices |
list | A 2 element long list which represents what subset of the text is formatted (include #). |
Link to another website.
"links": [{
"text": "this new site",
"url": "https://join.app.net"
"indices": [20, 32],
}]
Field | Type | Description |
---|---|---|
text |
string | The anchor text to be linked (could be a url). |
url |
string | The destination url (only http or https accepted). |
indices |
list | A 2 element long list which represents what subset of the text is linked. |
A Filter functions as either a whitelist or a blacklist over a stream of Posts. All the predicates are logically OR'ed together. For instance, with the following example, a post will be shown if it's from user 1, or it's from user 2, or it has hashtag 'sf', or it links to app.net, or it mentions user 1.
{
"id": "1",
"type": "show",
"name": "On the go",
"user_ids": ["1", "2"],
"hashtags": ["sf"],
"link_domains": ["app.net"],
"mention_user_ids": ["1"]
}
Field | Type | Description |
---|---|---|
type |
string | Either show or block for whether this filter should exclude everything except for what's shown or show everything except for what's blocked. |
name |
string | A User assigned name for this filter. |
user_ids |
list | A list of user ids a Post must or must not be created by. |
hashtags |
list | A list of hashtags a Post must or must not have. |
link_domains |
list | A list of domains a Post must or must not have a link to. |
mention_user_ids |
list | A list of user ids a Post must or must not mention. |
Dates will be formatted as a strict subset of ISO 8601. Dates are parseable by almost any ISO 8601 date parser or merely by parsing from position. All dates will be formatted as follows:
2012-12-31T13:22:55Z
where 2012
is the year, 12
represents December, 31
represents the 31st day of the month, 13
represents 1 PM, 22
minutes and 55
seconds past the hour. All times will be expressed in terms of UTC.
This format was chosen to minimize ambiguity and edge cases in terms of parsing while maximizing readability of dates during development.
If you are storing object IDs, ensure that you store them as strings, not integers. IDs may at some future point contain any printable 7-bit ASCII character, even if these example data structures only have numeric IDs.