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",
"pos": 52,
"len": 10
}],
"hashtags": [{
"name": "api",
"pos": 70,
"len": 4
}],
"links": [{
"text": "teaching you",
"url": "https://github.com/appdotnet/api-spec",
"pos": 29,
"len": 12
}]
}
},
"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": {...}
},
"follows_you": false,
"you_follow": true,
"you_muted": false,
}
Field | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id |
string | Primary identifier for a user. This will be an integer, but it is always expressed as a string to avoid limitations with the way JavaScript integers are expressed. This idspace is unique to User 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). | ||||||||||||
follows_you |
boolean | Does this user follow the user making the request? May be omitted if this is not an authenticated request. | ||||||||||||
you_follow |
boolean | Does the user making the request follow this user? May be omitted if this is not an authenticated request. | ||||||||||||
you_muted |
boolean | Has the user making the request blocked this user? May be omitted if this is not an authenticated request. |
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,
"thread_id": "1",
"num_replies": 3,
"annotations": {
"wellknown:geo": {
"type": "Point",
"coordinates": [102.0, .5]
}
},
"entities": {
"mentions": [{
"name": "berg",
"id": "2",
"pos": 0,
"len": 5
}],
"hashtags": [{
"name": "newsocialnetwork",
"pos": 34,
"len": 17
}],
"links": [{
"text": "this new site",
"url": "https://join.app.net"
"pos": 20,
"len": 13
}]
}
}
Field | Type | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
id |
string | Primary identifier for a post. This will be an integer, but it is always expressed as a string to avoid limitations with the way JavaScript integers are expressed. | |||||||||
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). |
|||||||||
thread_id |
string | The id of the post at the root of the thread that this post is a part of. If thread_id==id than this property does not guarantee that the thread has > 1 post. Please see num_replies . |
|||||||||
num_replies |
integer | The number of posts created in reply to this post. | |||||||||
annotations |
object | Metadata about the entire post. See the annotations documentation. | |||||||||
entities |
object | Rich text information for this post. See the entities documentation. | |||||||||
is_deleted |
boolean | Has this post been deleted? For non-deleted posts, this key may be omitted instead of being false . If a post has been deleted, the text , html , and entities properties will be empty and may be omitted. |
- 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",
"pos": 0,
"len": 5,
}]
Field | Type | Description |
---|---|---|
name |
string | The username being mentioned (doesn't include '@'). |
id |
string | The user id of the mentioned user. |
pos |
integer | The 0 based index where this entity begins text (include @). |
len |
integer | The length of the substring in text that represents this mention. Since @ is included, len will be the length of the name + 1. |
Tag a post about a specific subject. A hashtag starts with #
.
"hashtags": [{
"name": "newsocialnetwork",
"pos": 34,
"len": 17
}]
Field | Type | Description |
---|---|---|
name |
string | The text of the hashtag (not including #). |
pos |
integer | The 0 based index where this entity begins text (include #). |
len |
integer | The length of the substring in text that represents this hashtag. Since # is included, len will be the length of the name + 1. |
Link to another website.
"links": [{
"text": "this new site",
"url": "https://join.app.net"
"pos": 20,
"len": 13
}]
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). |
pos |
integer | The 0 based index where this entity begins text . |
len |
integer | The length of the substring in text that represents this link. |
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.
Object ids will always be transferred as strings to avoid issues with with limitations of JavaScript integers. You can assume that object ids are integers.