23 |
--------------------------------------------------------------------------------
/content/reference/resources/post/report.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Report"
3 | ---
4 |
5 | # Report
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Report a Post
11 |
12 | Report a post as spam. This will mute the author of the post and send a report to App.net.
13 |
14 | > If you are testing this endpoint, please send an email to [support@app.net](mailto:support@app.net) letting us know the account you are about to report.
15 |
16 | <%= general_params_note_for "post" %>
17 |
18 | <%= endpoint "POST", "posts/[post_id]/report", "User" %>
19 |
20 | <%= url_params [
21 | ["post_id", "The id of the Post to report."]
22 | ]%>
23 |
24 | #### Example
25 |
26 | <%= curl_example(:post, "posts/#{get_id(:post)}/report", :post) %>
27 |
--------------------------------------------------------------------------------
/layouts/partials/endpoint.md:
--------------------------------------------------------------------------------
1 | #### Endpoint
2 |
3 |
4 |
5 |
6 |
Method
7 |
URL
8 |
Token
9 | <% if scope != '' %>
10 |
Scope
11 | <% end %>
12 |
13 |
14 |
15 |
16 |
<%= method %>
17 |
<%= path %>
18 |
<%= token %>
19 | <% if scope != '' %>
20 |
<%= scope %>
21 | <% end %>
22 |
23 |
24 |
--------------------------------------------------------------------------------
/content/reference/resources/user/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Search"
3 | ---
4 |
5 | # Search
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Search for Users
11 |
12 | Search the App.net userbase.
13 |
14 | <%= general_params_note_for "user" %>
15 |
16 | <%= endpoint "GET", "users/search", "Any" %>
17 |
18 | <%= query_params [
19 | ["q","The search query. Supports @username or #tag searches as well as normal search terms. Searches username, display name, bio information. Does not search posts."],
20 | ["count","(Optional) The number of Users to return, up to a maximum of 200. Defaults to 20 if not specified."]
21 | ]%>
22 |
23 | #### Example
24 |
25 | <%= curl_example(:get, "users/search?q=%23api", :user, {:response => :paginated}) do |h|
26 | h["meta"]["count"] = 1
27 | h["data"][0]["pagination_id"] = "10000"
28 | end %>
29 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/place.md:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/content/reference/resources/post/replies.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Post Replies"
3 | ---
4 |
5 | # Replies
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve the replies to a Post
11 |
12 | Retrieve all the [Posts](/reference/resources/post/) that are in the same thread as this post. The specified Post does not have to be the root of the conversation. Additionally, the specified Post will be included in the response at the appropriate place.
13 |
14 | **This endpoint would be more accurately named `stream/0/posts/{post_id}/thread` and may be renamed in a later API version.**
15 |
16 | <%= general_params_note_for "post" %>
17 |
18 | <%= pagination_note %>
19 |
20 | <%= endpoint "GET", "posts/[post_id]/replies", "Any" %>
21 |
22 | <%= url_params [
23 | ["post_id","The id of a Post in the thread to retrieve."]
24 | ]%>
25 |
26 | #### Example
27 |
28 | <%= curl_example(:get, "posts/#{get_id(:post)}/replies", :post_reply, {:response => :paginated}) %>
29 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/explore-stream.md:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/content/reference/make-request/data-formats.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Data Formats"
3 | ---
4 |
5 | # Notes on data formats
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Dates
11 |
12 | Dates will be formatted as a **strict** subset of [ISO 8601](http://en.wikipedia.org/wiki/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:
13 |
14 | `2012-12-31T13:22:55Z`
15 |
16 | 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.
17 |
18 | This format was chosen to minimize ambiguity and edge cases in terms of parsing while maximizing readability of dates during
19 | development.
20 |
21 | ## Object IDs
22 |
23 | 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.
24 |
--------------------------------------------------------------------------------
/layouts/partials/top_nav.html:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/content/reference/authentication/flows/sdk.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Authorize via App.net SDK"
3 | ---
4 |
5 | # Authorize via App.net SDK
6 |
7 | On iOS and Android, App.net provides SDKs to streamline the process of a user authenticating your app. This is also the easiest way for a new user to sign up for App.net via their mobile device. Both SDKs work in similar ways:
8 |
9 | 1. The developer integrates the SDK into their native app
10 | 2. The developer shows the user a "Log in" button
11 | 3. When the user taps that button, they are taken to the Official App.net App.
12 | 4. Once the user authorizes the developer's app, the Official App.net App returns the user to the developer's app with an access token.
13 |
14 | ## iOS
15 |
16 | The [iOS Login SDK](https://github.com/appdotnet/ADNLogin-SDK-iOS) is hosted on Github with complete installation instructions.
17 |
18 | ## Android
19 |
20 | The [Android Login SDK](https://github.com/appdotnet/ADNLogin-SDK-Android) is hosted on Github with complete installation instructions.
21 |
--------------------------------------------------------------------------------
/content/reference/resources/post/lookup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Post Lookup"
3 | ---
4 |
5 | # Lookup
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve a Post
11 |
12 | Returns a specific [Post](/reference/resources/post/).
13 |
14 | <%= general_params_note_for "post" %>
15 |
16 | <%= endpoint "GET", "posts/[post_id]", "None" %>
17 |
18 | <%= url_params [
19 | ["post_id","The id of the Post to retrieve."]
20 | ]%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:get, "posts/#{get_id(:post)}", :post) %>
25 |
26 | ## Retrieve multiple Posts
27 |
28 | Returns multiple Posts requested by id. At most 200 posts can be requested.
29 |
30 | <%= general_params_note_for "post" %>
31 |
32 | <%= endpoint "GET", "posts", "Any" %>
33 |
34 | <%= query_params [
35 | ["ids","A comma separated list of ids of Posts to retrieve."]
36 | ]%>
37 |
38 | #### Example
39 |
40 | <%= curl_example(:get, "posts?ids=#{get_id(:post)},2", :post, {:response => :collection}) do |h|
41 | second = h["data"][0].clone()
42 | second["id"] = "2"
43 | h["data"].unshift(second)
44 | end %>
45 |
--------------------------------------------------------------------------------
/content/reference/resources/user/post-interactions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Post Interactions"
3 | ---
4 |
5 | # Post Interactions
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## List Users who have reposted a Post
11 |
12 | List all the Users who have reposted a given Post.
13 |
14 | <%= general_params_note_for "user" %>
15 |
16 | <%= endpoint "GET", "posts/[post_id]/reposters", "Any" %>
17 |
18 | <%= url_params [
19 | ["post_id","The id of the target Post."]
20 | ]%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:get, "posts/1/reposters", :user, {:response => :paginated}) do |h|
25 | h["data"][0]["pagination_id"] = "345"
26 | h["meta"]["more"] = true
27 | end %>
28 |
29 | ## List Users who have starred a Post
30 |
31 | List all the Users who have starred a given Post.
32 |
33 | <%= general_params_note_for "user" %>
34 |
35 | <%= endpoint "GET", "posts/[post_id]/stars", "Any" %>
36 |
37 | <%= url_params [
38 | ["post_id","The id of the target post."]
39 | ]%>
40 |
41 | #### Example
42 |
43 | <%= curl_example(:get, "posts/1/stars", :user, {:response => :paginated}) do |h|
44 | h["data"][0]["pagination_id"] = "1356"
45 | h["meta"]["more"] = true
46 | end %>
47 |
--------------------------------------------------------------------------------
/content/reference/resources/user/lookup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Lookup"
3 | ---
4 |
5 | # Lookup
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve a User
11 |
12 | Returns a specific User object.
13 |
14 | <%= general_params_note_for "user" %>
15 |
16 | <%= endpoint "GET", "users/[user_id]", "None" %>
17 |
18 | <%= url_params [
19 | ["user_id","The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
20 | ]%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:get, "users/#{get_id(:user)}", :user) %>
25 |
26 | ## Retrieve multiple Users
27 | Returns multiple Users requested by id. At most 200 users can be requested.
28 |
29 | <%= general_params_note_for "user" %>
30 |
31 | <%= endpoint "GET", "users", "Any" %>
32 |
33 | <%= query_params [
34 | ["ids","A comma separated list of User ids to retrieve."]
35 | ]%>
36 |
37 | #### Example
38 |
39 | <%= curl_example(:get, "users?ids=1,2", :user, {:response => :collection}) do |h|
40 | second = h["data"][0].clone()
41 | second["id"] = "2"
42 | h["data"].unshift(second)
43 | end %>
44 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/token.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/content/docs/guides/create-a-post.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Create a Post"
3 | ---
4 |
5 | # Creating a Post via the API
6 |
7 | <%= access_token_required_note %>
8 |
9 | A [Post](/reference/resources/post) is the microblogging primitive of the App.net API. When a user creates a post, it appears in all of their follower's streams. Posts can have images, links, and annotations but at their simplest, they just contain a piece of text.
10 |
11 | ## Create a post
12 |
13 | The easiest way to create a post is to use [one of the API libraries](/docs/libraries).
14 |
15 | Using [adnpy](/docs/libraries#python)
16 |
17 | ~~~ python
18 | import adnpy
19 |
20 | # Set the default access token for API calls.
21 | adnpy.api.add_authorization_token('')
22 |
23 | # Create a post
24 | post = adnpy.api.create_post(data={'text':'Hello App.net from Python!'})
25 | ~~~
26 |
27 | Or with the [adn](/docs/libraries#ruby) Ruby gem:
28 |
29 | ~~~ ruby
30 | require 'adn'
31 |
32 | ADN.token = ''
33 | post = ADN::Post.send_post(:text => "Hello App.net from Ruby!")
34 | ~~~
35 |
36 | If you want to send the equivalent broadcast from the API without using a library, use this curl command:
37 |
38 | <%= curl_example(:post, "posts", :none, {:data => {"text" => "Hello App.net from curl!"}}) %>
39 |
--------------------------------------------------------------------------------
/content/reference/other/oembed.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "oEmbed"
3 | ---
4 |
5 | # oEmbed
6 |
7 | oEmbed is an open standard for turning a URL into an embeddable piece of content for your site. To find out more about oEmbed [read the spec](http://www.oembed.com/). The App.net oEmbed endpoint will return HTML snippets that you can include on your site. Right now it works for individual posts, and photos.
8 |
9 |
10 | ## oEmbed Endpoint
11 |
12 | Returns an oEmbed response for a given URL.
13 |
14 | <%= endpoint "GET", "oembed", "None", '', '' %>
15 |
16 | <%= url_params [
17 | ["url", "A URL for a post or photo on App.net."]
18 | ]%>
19 |
20 | #### Example
21 |
22 | <% response = {
23 | "provider_url" => "https://app.net",
24 | "version" => "1.0",
25 | "author_url" => "https://alpha.app.net/mthurman",
26 | "title" => "join.app.net getting ready for the world w/ @dalton @berg @voidfiles @jhubball @aaronblyth @andrew @vinitlee @mark @mintz @barmstrong @laughingman @mikegreenspan @ben #joinus",
27 | "url" => "https://alpha.app.net/mthurman/post/1",
28 | "provider_name" => "App.net",
29 | "type" => "link",
30 | "html" => "...",
31 | "author_name" => "mthurman"
32 | } %>
33 |
34 | <%= curl_example(:get, "oembed?url=https://posts.app.net/1", response, {:path_prefix => "/"}) %>
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # developers.app.net
2 |
3 | This branch (new-docs) of the appdotnet/api-spec repo contains the source for [developers.app.net](http://developers.app.net/) and replaces the docs located on the master branch.
4 |
5 | This documentation can be compiled using [nanoc](http://nanoc.stoneship.org/).
6 |
7 | All submissions are welcome. To submit a change, fork this repo, commit your changes, and send us a [pull request](http://help.github.com/send-pull-requests/).
8 |
9 | ## Building the docs
10 |
11 | Ruby is required to build the site.
12 |
13 | To install nanoc and make sure you have all the necessary ruby gems, open a terminal in the root of the api-spec checkout and run
14 |
15 | $ bundle install
16 |
17 | To compile the docs for the first time, run
18 |
19 | $ bundle exec nanoc
20 |
21 | Nanoc compiles the site into static files living in `./output`.
22 |
23 | In general, the best way to work on the docs is like this:
24 |
25 | $ bundle exec nanoc view &
26 | $ bundle exec guard start
27 |
28 | Guard will run and auto-generate new HTML output when you edit Markdown files, and the nanoc built-in webserver will be available on http://localhost:3000/
29 |
30 | If you want to learn more about using nanoc, view the [nanoc documentation](http://nanoc.stoneship.org/docs/1-introduction/).
31 |
--------------------------------------------------------------------------------
/Rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # A few helpful tips about the Rules file:
4 | #
5 | # * The string given to #compile and #route are matching patterns for
6 | # identifiers--not for paths. Therefore, you can’t match on extension.
7 | #
8 | # * The order of rules is important: for each item, only the first matching
9 | # rule is applied.
10 | #
11 | # * Item identifiers start and end with a slash (e.g. “/about/” for the file
12 | # “content/about.html”). To select all children, grandchildren, … of an
13 | # item, use the pattern “/about/*/”; “/about/*” will also select the parent,
14 | # because “*” matches zero or more characters.
15 |
16 | compile '/assets/js/*' do
17 | filter :erb
18 | end
19 |
20 | compile '/static/*' do
21 | end
22 |
23 | compile '/nginx' do
24 | filter :erb, :trim_mode =>"<>"
25 | end
26 |
27 | compile '*' do
28 | if item.binary?
29 | # don’t filter binary items
30 | else
31 | filter :erb
32 | filter :kramdown, :toc_levels => [2], :enable_coderay => false
33 | filter :colorize_syntax, :default_colorizer => :pygmentsrb, :linenos => 'inline'
34 | layout 'default'
35 | end
36 | end
37 |
38 | route '/nginx' do
39 | '/nginx.conf'
40 | end
41 |
42 | route '/static/*' do
43 | '/assets'+item.identifier[7..-2]
44 | end
45 |
46 | route '/assets/js/*' do
47 | item.identifier.chop + '.' + item[:extension]
48 | end
49 |
50 | route '*' do
51 | if item.binary?
52 | # Write item with identifier /foo/ to /foo.ext
53 | item.identifier.chop + '.' + item[:extension]
54 | else
55 | # Write item with identifier /foo/ to /foo/index.html
56 | item.identifier + 'index.html'
57 | end
58 | end
59 |
60 | layout '*', :erb
61 |
--------------------------------------------------------------------------------
/content/reference/resources/file/lookup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "File Lookup"
3 | ---
4 |
5 | # Lookup
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve a File
11 |
12 | Returns a specific [File](/reference/resources/file/).
13 |
14 | <%= general_params_note_for "file" %>
15 |
16 | <%= endpoint "GET", "files/[file_id]", "Varies"%>
17 |
18 | <%= file_token_reminder %>
19 |
20 | <%= url_params [
21 | ["file_id", "The id of the File to retrieve."]
22 | ]%>
23 |
24 | #### Example
25 |
26 | <%= curl_example(:get, "files/1", :file) %>
27 |
28 | ## Retrieve multiple Files
29 |
30 | Returns multiple Files requested by id. At most 200 files can be requested. Files which do not exist or which the requesting user does not have authorization to view will not be returned.
31 |
32 | <%= general_params_note_for "file" %>
33 |
34 | <%= endpoint "GET", "files", "User", "files"%>
35 |
36 | <%= file_token_reminder %>
37 |
38 | <%= query_params [
39 | ["ids", "A comma separated list of File ids to retrieve."]
40 | ]%>
41 |
42 | #### Example
43 |
44 | In the following example, file 6502 is omitted because it doesn't exist or we don't have permission to view it.
45 |
46 | <%= curl_example(:get, "files?ids=1,2,6502", :file, {:response => :collection}) do |h|
47 | second = h["data"][0].clone()
48 | second["id"] = "2"
49 | h["data"].unshift(second)
50 | end %>
51 |
52 | ## Retrieve my Files
53 |
54 | Returns a stream of all Files the current user has created.
55 |
56 | <%= general_params_note_for "file" %>
57 |
58 | <%= pagination_note %>
59 |
60 | <%= endpoint "GET", "users/me/files", "User", "files"%>
61 |
62 | #### Example
63 |
64 | <%= curl_example(:get, "users/me/files", :file, {:response => :paginated}) %>
65 |
--------------------------------------------------------------------------------
/content/reference/authentication/flows/app-access-token.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "App Access Token Flow"
3 | ---
4 |
5 | # App Access Token Flow
6 |
7 | * TOC
8 | {:toc}
9 |
10 | The App Access Token Flow is used to request a token that is tied to your application instead of a specific user. **App access tokens cannot be distributed and must only be used from a server. You should consider them secret.** If you would like a client (i.e. mobile) application to use an app access token, that app must connect to a server you control that stores the app access token.
11 |
12 | To retrieve an app access token, your app must make the following request:
13 |
14 | POST https://account.app.net/oauth/access_token
15 |
16 | with URL-encoded POST body:
17 |
18 | client_id=[your client ID]
19 | &client_secret=[your client secret]
20 | &grant_type=client_credentials
21 |
22 | Example:
23 |
24 | <%= curl_example(:post, "access_token", :none, {
25 | :subdomain => "account",
26 | :path_prefix => "/oauth/",
27 | :pretty_json => false,
28 | :token => nil,
29 | :content_type => nil,
30 | :data => {
31 | "grant_type" => "client_credentials",
32 | "client_id" => "[your client_id]",
33 | "client_secret" => "[your client secret]",
34 | }
35 | }) %>
36 |
37 |
38 | > We also accept the `client_id` and `client_secret` parameters via the Authorization header, as described in [section 2.3.1 of the OAuth 2 spec](http://tools.ietf.org/html/rfc6749#section-2.3.1).
39 |
40 | App.net will respond with a JSON-encoded token:
41 |
42 | {"access_token": "[app access token]", "token": {...Token object...}}
43 |
44 | You can use this access_token to make authenticated calls to the App.net API on behalf of your app.
45 |
--------------------------------------------------------------------------------
/content/reference/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "App.net API Reference"
3 | ---
4 | # App.net API Reference
5 |
6 | These pages contain the complete specification of how the App.net API works. We try to follow standard practices to make our API easy to use from one of our [client libraries](/docs/libraries/) or from any normal HTTP client.
7 |
8 | ## Authentication
9 |
10 | We use the [OAuth 2.0 protocol](http://tools.ietf.org/html/rfc6749) to authenticate clients to the API. There are multiple ways to get a token to a user's account. Please read our [Authentication Overview](/reference/authentication/) to choose the right one for your app.
11 |
12 | ## Responses
13 |
14 | Our [API responses](/reference/make-request/responses/) are always JSON encoded. We use HTTP status codes to indicate success or failures.
15 |
16 | ## Migrations
17 |
18 | From time to time, we'll need to change the API. If we change the behavior of an endpoint or remove a field, we will provide a migration so clients can opt into the new behavior when their code is updated. [Migrations](/reference/make-request/migrations) are our way of versioning the App.net API. They allow your app the flexibility to control which version of the API it uses on a per request or global basis.
19 |
20 | ## Rate Limits
21 |
22 | In order to ensure a high quality of service and prevent abuse, our API is rate limited. We use standard HTTP headers and status codes to rate limit requests. For more information (and to view the current rate limits), please see the [Rate Limits documentation](/reference/make-request/rate-limits/).
23 |
24 | ## Errors
25 |
26 | If there is an error, we return an [HTTP status code](/reference/make-request/responses/#possible-http-status-codes) and a JSON response describing it.
27 |
28 |
--------------------------------------------------------------------------------
/content/reference/resources/message/lookup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Message Lookup"
3 | ---
4 |
5 | # Lookup
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve a Message
11 |
12 | Returns a specific [Message](/reference/resources/message/).
13 |
14 | *You can always retrieve a message you created even if you are no longer able to view the rest of the Channel anymore.*
15 |
16 | <%= general_params_note_for "message" %>
17 |
18 | <%= endpoint "GET", "channels/[channel_id]/messages/[message_id]", "Any" %>
19 |
20 | <%= url_params [
21 | ["channel_id", "The id of the Channel containing the Message."],
22 | ["message_id", "The id of the Message to retrieve."]
23 | ]%>
24 |
25 | #### Example
26 |
27 | <%= curl_example(:get, "channels/1/messages/1", :message) %>
28 |
29 | ## Retrieve multiple Messages
30 |
31 | Returns multiple Messages requested by id. At most 200 messages can be requested. Messages may be requested from more than one channel at a time. Messages which do not exist or which the requesting user does not have authorization to view will not be returned.
32 |
33 | <%= general_params_note_for "message" %>
34 |
35 | <%= endpoint "GET", "channels/messages", "Any" %>
36 |
37 | <%= query_params [
38 | ["ids", "A comma separated list of ids of the Messages to retrieve."]
39 | ]%>
40 |
41 | #### Example
42 |
43 | <%= curl_example(:get, "channels/messages?ids=1,2", :message, {:response => :collection}) %>
44 |
45 | ## Retrieve my Messages
46 |
47 | Retrieve a stream of the Messages the current user has created.
48 |
49 | <%= general_params_note_for "message" %>
50 |
51 | <%= pagination_note %>
52 |
53 | <%= endpoint "GET", "users/me/messages", "User", "public_messages or messages" %>
54 |
55 | #### Example
56 |
57 | <%= curl_example(:get, "users/me/messages", :message, {:response => :paginated}) %>
58 |
--------------------------------------------------------------------------------
/content/reference/resources/token/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Token"
3 | ---
4 |
5 | # Token
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve current token
11 |
12 | Returns info about the current [OAuth access token](/reference/authentication/#access-tokens). If the token is a user token the response will include a [User](/reference/resources/user/) object.
13 |
14 | <%= endpoint "GET", "token", "Any" %>
15 |
16 | #### Example (App Token)
17 |
18 | <%= curl_example(:get, "token", :user_token, {:token => ""}) %>
19 |
20 | #### Example (User Token)
21 |
22 | <%= curl_example(:get, "token", :user_token) %>
23 |
24 |
25 | ## Deauthorize current token
26 |
27 | Deauthorize the current [OAuth access token](/reference/authentication/#access-tokens). This works for User tokens and App tokens.
28 |
29 | <%= endpoint "DELETE", "token", "Any" %>
30 |
31 | #### Example
32 |
33 | Requested with a user access token:
34 |
35 | <%= curl_example(:delete, "token", :user_token) %>
36 |
37 | ## Retrieve authorized User IDs for an app
38 |
39 | Returns a list of ids of Users that have authorized an app. Must be requested using an [app access token](/reference/authentication/#access-tokens).
40 |
41 | <%= endpoint "GET", "apps/me/tokens/user_ids", "App" %>
42 |
43 | #### Example
44 |
45 | <%= curl_example(:get, "apps/me/tokens/user_ids", ["2", "3"], {:token => ""}) %>
46 |
47 | ## Retrieve authorized User tokens for an app
48 |
49 | Returns a list of User tokens corresponding to an app token. Must be requested using an [app access token](/reference/authentication/#access-tokens).
50 |
51 | <%= pagination_note %>
52 |
53 | <%= endpoint "GET", "apps/me/tokens", "App" %>
54 |
55 | #### Example
56 |
57 | <%= curl_example(:get, "apps/me/tokens", :user_token, {:response => :paginated, :token => ""}) do |h|
58 | h["data"][0]["pagination_id"] = "10723"
59 | end %>
60 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/filter.md:
--------------------------------------------------------------------------------
1 |
49 |
--------------------------------------------------------------------------------
/content/reference/resources/user-stream/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Stream Lifecycle"
3 | ---
4 |
5 | # User Stream Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Delete a User Stream
11 |
12 | Delete a [User Stream](/reference/resources/user-stream/). The User Stream must belong to the current token. It disconnects any sockets with this User Stream open and returns an HTTP 204 No Content on success.
13 |
14 | If you'd like your user stream to be automatically deleted when you disconnect from it, please add the [`auto_delete=1`](/reference/resources/user-stream/#limits) query string parameter when you create the user stream.
15 |
16 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
17 |
18 | <%= endpoint "DELETE", "users/me/streams/[connection_id]", "User" %>
19 |
20 | <%= url_params [
21 | ["connection_id", "The connection id of the User Stream to delete."]
22 | ]%>
23 |
24 | ### Example
25 |
26 | <%= curl_example(:delete, "streams/sxousNClc4Cq12du3f6GTZXNUvaHoJnFnjdOt6fH2xhJolPdDfR3rOxxjdPfPOIf", "204 No Content", {
27 | :response => :raw
28 | }) %>
29 |
30 |
31 | ## Delete a User Stream subscription
32 |
33 | Delete a subscription of a [User Stream](/reference/resources/user-stream/). The User Stream must belong to the current token. It returns an HTTP 204 No Content on success.
34 |
35 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
36 |
37 | <%= endpoint "DELETE", "users/me/streams/[connection_id]/[subscription_id]", "User" %>
38 |
39 | <%= url_params [
40 | ["connection_id", "The connection id of the User Stream the subscription belongs to."],
41 | ["subscription_id", "The subscription id of the subscription to cancel"]
42 | ]%>
43 |
44 | ### Example
45 |
46 | <%= curl_example(:delete, "streams/sxousNClc4Cq12du3f6GTZXNUvaHoJnFnjdOt6fH2xhJolPdDfR3rOxxjdPfPOIf/bf42ca05-e67e-4e26-8bd0-8b042dd5b04c", "204 No Content", {
47 | :response => :raw
48 | }) %>
49 |
--------------------------------------------------------------------------------
/content/reference/authentication/authorize-with-appnet.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Web Flow Integration Guide"
3 | ---
4 |
5 | # Web Flow Integration Guide
6 |
7 | Now that you've identified which [web flow](/reference/authentication/flows/web/) to use with your app, it's time to expose this to end users.
8 |
9 | * TOC
10 | {:toc}
11 |
12 | ## Authorize With App.net Button
13 |
14 | The easiest way to integrate a web flow into your app is through an "Authorize with App.net" Button, which allows current App.net users to enjoy the ease of authorizing your app in two clicks. Less means more, as they'll be able to start using your app even faster.
15 |
16 | As an added benefit, this button will also allow new users to sign up for a free account and then authorize your app.
17 |
18 | ### Benefits
19 |
20 | 1. **It's easy**: Add an Authorize with App.net button to your site in seconds.
21 | 1. **It's beautiful**: The minimal style of the button is versatile and users will recognize the App.net branding.
22 | 1. **It's useful**: Your potential users can either sign up or sign in to your app with the same button.
23 |
24 | ### Implementation
25 |
26 | To implement the button on your site, you must:
27 |
28 | 1. Build [Your authentication URL](/reference/authentication/flows/web/).
29 | 1. Replace the variables inside the brackets
30 | 1. Copy and paste the snippet below into your HTML where you want the button to show up
31 |
32 |
33 | ~~~html
34 | Authorize with App.net
35 | ~~~
36 |
37 | If you do everything correctly you should see a button like this:
38 |
39 | 
40 |
41 | ### Best Practices
42 |
43 | We suggest that you put the following copy directly above or below the button:
44 |
45 | An App.net account is required to use [Your App Name]. You can create an account and sign in by clicking this button.
--------------------------------------------------------------------------------
/content/reference/resources/channel/muting.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Channel Muting"
3 | ---
4 |
5 | # Channel Muting
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Get current user's muted Channels
11 |
12 | Retrieve a list of the channels the current user has muted. A user cannot be [auto-subscribed](/docs/guides/messaging/#subscriptions) to muted channels.
13 |
14 | This endpoint is **not** paginated and does **not** respond to the [general channel parameters](/reference/resources/channel/#general-parameters).
15 |
16 | <%= endpoint "GET", "users/me/channels/muted", "User", "public_messages or messages"%>
17 |
18 | #### Example
19 |
20 | <%= curl_example(:get, "users/me/channels/muted", :channel, {:response => :collection}) do |h|
21 | h["data"][0]["you_muted"] = true
22 | end %>
23 |
24 | ## Mute a Channel
25 |
26 | Mute a Channel. If a user doesn't want to see a channel until there is a new message, they should [unsubscribe from the channel](/reference/resources/channel/subscriptions/#unsubscribe-from-a-channel) instead of muting it. If a user mutes a channel, they will automatically be unsubscribed from it and cannot be [auto-subscribed](/docs/guides/messaging/#subscriptions) to it.
27 |
28 | <%= general_params_note_for "channel" %>
29 |
30 | <%= endpoint "POST", "channels/[channel_id]/mute", "User", "public_messages or messages"%>
31 |
32 | <%= url_params [
33 | ["channel_id", "The id of the Channel to mute."]
34 | ]%>
35 |
36 | #### Example
37 |
38 | <%= curl_example(:post, "channels/1/mute", :channel) do |h|
39 | h["data"]["you_muted"] = true
40 | h["data"]["you_subscribed"] = false
41 | end %>
42 |
43 | ## Unmute a Channel
44 |
45 | Unmute a Channel. This allows you to be resubscribed to the channel (but it does not happen automatically).
46 |
47 | <%= general_params_note_for "channel" %>
48 |
49 | <%= endpoint "DELETE", "channels/[channel_id]/mute", "User", "public_messages or messages"%>
50 |
51 | <%= url_params [
52 | ["channel_id", "The id of the Channel to unmute."]
53 | ]%>
54 |
55 | #### Example
56 |
57 | <%= curl_example(:delete, "channels/1/mute", :channel) do |h|
58 | h["data"]["you_muted"] = false
59 | h["data"]["you_subscribed"] = false
60 | end %>
61 |
--------------------------------------------------------------------------------
/content/reference/resources/post/stars.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Stars"
3 | ---
4 |
5 | # Stars
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Star a Post
11 |
12 | Save a given Post to the current User's stars. This is just a "save" action, not a sharing action. A User's stars are visible to others, but they are not automatically added to your followers' streams.
13 |
14 | *A repost cannot be starred. Please star the parent Post.*
15 |
16 | <%= general_params_note_for "post" %>
17 |
18 | <%= endpoint "POST", "posts/[post_id]/star", "User", "write_post" %>
19 |
20 | <%= url_params [
21 | ["post_id", "The id of the Post to star."]
22 | ]%>
23 |
24 | #### Example
25 |
26 | <%= curl_example(:get, "posts/#{get_id(:post)}/star", :post) do |h|
27 | h["data"]["num_stars"] += 1
28 | h["data"]["you_starred"] = true
29 | end %>
30 |
31 | ## Unstar a Post
32 |
33 | Remove a Star from a Post.
34 |
35 | <%= general_params_note_for "post" %>
36 |
37 | <%= endpoint "DELETE", "posts/[post_id]/star", "User", "write_post" %>
38 |
39 | <%= url_params [
40 | ["post_id", "The id of the Post to unstar."]
41 | ]%>
42 |
43 | #### Example
44 |
45 | <%= curl_example(:delete, "posts/#{get_id(:post)}/star", :post) do |h|
46 | h["data"]["you_starred"] = false
47 | end %>
48 |
49 | ## Retrieve Posts starred by a User
50 |
51 | Get the most recent [Posts](/reference/resources/post/) starred by a specific [User](/reference/resources/user/) in reverse post order. Stars are a way for Users to save posts without rebroadcasting the Post to their followers.
52 |
53 | <%= general_params_note_for "post" %>
54 |
55 | <%= pagination_note %>
56 |
57 | <%= endpoint "GET", "users/[user_id]/stars", "None" %>
58 |
59 | <%= url_params [
60 | ["user_id", "The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
61 | ]%>
62 |
63 | *See [General Parameters](/reference/resources/post/#general-parameters) for optional parameters you can use with this query.*
64 |
65 | #### Example
66 |
67 | <%= curl_example(:get, "users/#{get_id(:user)}/stars", :post, {:response => :paginated}) do |h|
68 | h["data"][0]["num_stars"] += 1
69 | h["data"][0]["you_starred"] = true
70 | end %>
--------------------------------------------------------------------------------
/content/reference/resources/text-processor/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Text Processor"
3 | ---
4 |
5 | # Text Processor
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Process text
11 |
12 | When a request is made to [create a Post](/reference/resources/post/lifecycle/#create-a-post) or [Message](/reference/resources/message/lifecycle/#create-a-message), or [update a User profile](/reference/resources/user/profile/#update-a-user) description, the provided body text is processed for [entities](/reference/meta/entities). You can use this endpoint to test how App.net will parse text for entities as well as render text as html. This endpoint must always be called with a JSON body as documented under [Post creation](/reference/resources/post/lifecycle/#create-a-post). Calls to this endpoint will not create or update any objects in App.net.
13 |
14 | <%= endpoint "POST", "text/process", "Any" %>
15 |
16 | <%= post_params [
17 | ["text", "The raw text to process."]
18 | ]%>
19 |
20 | #### Example
21 |
22 | <% response = {
23 | "entities" => {
24 | "hashtags" => [
25 | {
26 | "len" => 8,
27 | "name" => "awesome",
28 | "pos" => 8
29 | }
30 | ],
31 | "links" => [
32 | {
33 | "len" => 17,
34 | "pos" => 39,
35 | "text" => "http://google.com",
36 | "url" => "http://google.com"
37 | }
38 | ],
39 | "mentions" => [
40 | {
41 | "id" => "3",
42 | "len" => 10,
43 | "name" => "voidfiles",
44 | "pos" => 22
45 | }
46 | ]
47 | },
48 | "html" => "This is #awesome tell @voidfiles about http://google.com",
49 | "text" => "This is #awesome tell @voidfiles about http://google.com"
50 | } %>
51 |
52 | <% data = {
53 | "text" => "This is #awesome tell @voidfiles about http://google.com"
54 | } %>
55 |
56 | <%= curl_example(:post, "text/process", response, {:data => data}) %>
57 |
--------------------------------------------------------------------------------
/content/reference/resources/post/reposts.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Reposts"
3 | ---
4 |
5 | # Reposts
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Repost a Post
11 |
12 | Share a Post (specified with post_id) with your followers. Reposts are intended solely as a routing mechanism; a repost's text, entities, and html are "inherited" from the original Post. If a user would like to quote, comment on, or alter a Post, reposts are not the solution. Reposts are meant to be pointers to another Post.
13 |
14 | For compatibility with clients who don't wish to show reposts specially, we set a repost's text field to be `>> @username: original text`. **Thus the text field could actually be slightly longer than 256 characters.** Most clients will probably want to display the original post (with some indication that is has been reposted). When rendering a repost, we recommend you pull most of your information from `repost_of` and make use of the `repost_of.reposters` field.
15 |
16 | - Reposts cannot be reposted, starred, or replied to. Please take those actions on the parent post.
17 | - Reposts do not show up in the hashtags, mentions or global streams.
18 | - A repost of Post A will only show up in a User's stream if they have not seen Post A (or another repost of Post A) in a reasonable amount of time (currently 1 week).
19 |
20 | <%= general_params_note_for "post" %>
21 |
22 | <%= endpoint "POST", "posts/[post_id]/repost", "User", "write_post" %>
23 |
24 | <%= url_params [
25 | ["post_id", "The id of the Post to repost."]
26 | ]%>
27 |
28 | #### Example
29 |
30 | <%= curl_example(:get, "posts/#{get_id(:post)}/repost", :repost) do |h|
31 | h["data"]["repost_of"]["you_reposted"] = true
32 | end %>
33 |
34 | ## Unrepost a Post
35 |
36 | Given the original `post_id`, delete the current user's repost. *This same functionality can be accomplished by [deleting using the repost's post_id](/reference/resources/post/lifecycle/#delete-a-post)*.
37 |
38 | <%= general_params_note_for "post" %>
39 |
40 | <%= endpoint "DELETE", "posts/[post_id]/repost", "User", "write_post" %>
41 |
42 | <%= url_params [
43 | ["post_id", "The id of the Post to unrepost."]
44 | ]%>
45 |
46 | #### Example
47 |
48 | <%= curl_example(:delete, "posts/#{get_id(:post)}/repost", :post) do |h|
49 | h["data"]["you_reposted"] = false
50 | end %>
--------------------------------------------------------------------------------
/layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | <%= @item[:title] %> - App.net API Documentation
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
55 |
--------------------------------------------------------------------------------
/content/assets/js/app.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var _token = null;
3 | var verify_token = function (token) {
4 | if (token && token.match(/^[\-_a-zA-Z0-9]{98}$/)) {
5 | return $.ajax({
6 | url: "https://alpha-api.<%= lanai_hostname %>/stream/0/token",
7 | headers: {
8 | "Authorization": "BEARER " + token
9 | }
10 | }).promise();
11 | } else {
12 | return $.Deferred().reject().promise();
13 | }
14 | };
15 |
16 | var Auth = {
17 | login: function (new_token) {
18 | var deferred = $.Deferred();
19 |
20 | var valid_token = verify_token(new_token);
21 | valid_token.fail(function () {
22 | if (_token === null && typeof(localStorage.token) !== 'undefined') {
23 | _token = JSON.parse(localStorage.token);
24 | }
25 | }).done(function () {
26 | _token = {
27 | user_token: new_token
28 | };
29 | localStorage.token = JSON.stringify(_token);
30 | }).always(function () {
31 | if (_token && _token.user_token) {
32 | deferred.resolve(_token);
33 | } else {
34 | deferred.reject();
35 | }
36 | });
37 |
38 | return deferred.promise();
39 | },
40 | logout: function () {
41 | localStorage.token = null;
42 | token = null;
43 | _is_logged_in = false;
44 | },
45 | verify_token: verify_token
46 | };
47 |
48 | ADN.auth = Auth;
49 | }());
50 |
51 | $(function() {
52 | // make it easy to upgrade scopes, if there's a new token just log in with that even if we're already logged in
53 | var new_token = $.url(window.location).fparam('access_token');
54 | var login = ADN.auth.login(new_token);
55 |
56 | login.fail(function () {
57 | $('.authorize-prompt').removeClass('hide');
58 | }).done(function (token) {
59 | var needle = "<YOUR ACCESS TOKEN>";
60 | $('pre code').each(function () {
61 | var el = $(this);
62 | el.html(el.html().replace(needle, token.user_token));
63 | });
64 | });
65 |
66 | $(".content h1, .content h2, .content h3, .content h4").each(function(e){
67 | var id = $(this).attr("id");
68 | if (!id) return;
69 |
70 | $(this).append("");
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/content/reference/resources/channel/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Channel Search"
3 | ---
4 |
5 | # Search
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Search for Channels
11 |
12 | Returns [Channel](/reference/resources/channel/) objects which match a given search query. Because channels have no inherent notion of description or name, we take textual data from common channel annotations which contain such fields, e.g. net.patter-app.settings. We also allow filtering on specific channel properties, such as channel type. No matter what query data is supplied, the search results will respect channel ACLs, and results are limited to non-private channels if the requesting access token does not have the messages scope.
13 |
14 | Separate lists of terms by spaces.
15 |
16 | <%= general_params_note_for "channel" %>
17 |
18 | <%= endpoint "GET", "channels/search", "User", "public_messages or messages" %>
19 |
20 | <%= query_params_typed 'General Parameters', [
21 |
22 | ["order", :optional, "string", "One of: popularity (default), id, or activity. Searches of ordering popularity are returned in an order that roughly matches the popularity of the channels. activity searches will order results roughly by time of last message (precise sorting of very recent messages is not guaranteed)."],
23 |
24 | ]%>
25 |
26 | <%= query_params_typed 'Search Query Parameters', [
27 |
28 | ["q", :optional, "string", "Searches any textual fields extracted from channel annotations. We may tweak which annotations and fields are included by this search over time."],
29 |
30 | ]%>
31 |
32 |
33 | <%= query_params_typed 'Filter Parameters', [
34 | ["type", :optional, "string", "Only include channels which were created with a specific channel type"],
35 | ["creator_id", :optional, "string", "Only include channels which were created by a user with a certain id"],
36 | ["tags", :optional, "string", "Only include channels which are tagged with certain tags. This data is extracted from channel annotations"],
37 | ["is_private", :optional, "boolean", "Only include channels which have any_user and public set to false for read and write ACLs"],
38 | ["is_public", :optional, "boolean", "Only include channels which have public set to true for read ACLs"],
39 |
40 | ]%>
41 |
42 | #### Example
43 |
44 | <%= curl_example(:get, "channels/search?q=kerbal&order=popularity", :channel, {:response => :paginated}) do |h|
45 | h["meta"]["count"] = 1
46 | h["data"][0]["pagination_id"] = "10000"
47 | end %>
48 |
--------------------------------------------------------------------------------
/content/reference/resources/explore/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Explore Stream"
3 | ---
4 |
5 | # Explore Stream
6 |
7 | * TOC
8 | {:toc}
9 |
10 | An Explore Stream is a subset of all public posts flowing through App.net's Global Stream. These Explore Streams are defined by App.net to provide developers and users new ways to discover posts. **We will be adding and removing Explore Streams so in your app please [Retrieve all Explore Streams](#retrieve-all-explore-streams) and cache that list for up to 24 hours instead of hardcoding the current Explore Streams into your app.**
11 |
12 | <%= json(:explore_stream) %>
13 |
14 | ## Explore Stream Fields
15 |
16 |
17 |
18 |
Field
19 |
Type
20 |
Description
21 |
22 |
23 |
slug
24 |
string
25 |
Primary identifier for an explore stream. A lowercase alphanumeric string.
26 |
27 |
28 |
title
29 |
string
30 |
A human-friendly name for this Explore Stream.
31 |
32 |
33 |
description
34 |
string
35 |
A short description of this Explore Stream for displaying to the User.
36 |
37 |
38 |
url
39 |
string
40 |
The fully qualified url to the Explore Stream.
41 |
42 |
43 |
44 | ## Retrieve all Explore Streams
45 |
46 | Retrieve a list of all Explore Streams. The list of Explore Streams are dynamic and will sometimes change. **Please cache them for 24 hours in your app.** Also, please note that this endpoint is not paginated.
47 |
48 | <%= endpoint "GET", "posts/stream/explore", "None" %>
49 |
50 | #### Example
51 |
52 | <%= curl_example(:get, "posts/stream/explore", :explore_stream, {:response => :collection}) %>
53 |
54 | ## Retrieve an Explore Stream
55 |
56 | Retrieve the Posts in an Explore Stream.
57 |
58 | <%= pagination_note %>
59 |
60 | <%= endpoint "GET", "posts/stream/explore/[slug]", "None" %>
61 |
62 | <%= url_params [
63 | ["slug", "The slug of the Explore Stream to retrieve."]
64 | ]%>
65 |
66 | #### Example
67 |
68 | <%= curl_example(:get, "posts/stream/explore/photos", :explore_stream, {:response => :paginated}) do |h|
69 | h["meta"].merge!({
70 | "max_id" => "3382496",
71 | "min_id" => "3382480",
72 | "marker" => {
73 | "name" => "explore:photos"
74 | },
75 | "explore_stream" => get_hash(:explore_stream)
76 | })
77 | h["data"] = ["...post objects..."]
78 | end %>
79 |
--------------------------------------------------------------------------------
/content/reference/resources/user/muting.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Muting"
3 | ---
4 |
5 | # Muting
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Mute a User
11 |
12 | Hide all posts for a User in all streams. *If you still explicitly request this User's stream or a Post from this User, it will not be hidden.*
13 |
14 | <%= general_params_note_for "user" %>
15 |
16 | <%= endpoint "POST", "users/[user_id]/mute", "User", "follow" %>
17 |
18 | <%= url_params [
19 | ["user_id","The id of the User to mute. You can also specify @username as a user_id."]
20 | ]%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:post, "users/#{get_id(:user)}/mute", :user) do |h|
25 | h["data"]["you_muted"] = true
26 | end %>
27 |
28 | ## Unmute a User
29 |
30 | Stop hiding all posts for a given user.
31 |
32 | <%= general_params_note_for "user" %>
33 |
34 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
35 |
36 | <%= endpoint "DELETE", "users/[user_id]/mute", "User", "follow" %>
37 |
38 | <%= url_params [
39 | ["user_id","The id of the User to mute. You can also specify @username as a user_id."]
40 | ]%>
41 |
42 | #### Example
43 |
44 | <%= curl_example(:delete, "users/#{get_id(:user)}/mute", :user) do |h|
45 | h["data"]["you_muted"] = false
46 | end %>
47 |
48 | ## List muted Users
49 |
50 | Retrieve a list of muted users.
51 |
52 | <%= general_params_note_for "user" %>
53 |
54 | <%= endpoint "GET", "users/[user_id]/muted", "Any" %>
55 |
56 | <%= url_params [
57 | ["user_id",'The id of the user to retrieve a list of muted users for. If requested with a user token you can request muted users for the current user by using me as the user id. If requested with an app token you can request muted users for any user that has authorized your app.']
58 | ]%>
59 |
60 | #### Example
61 |
62 | <%= curl_example(:get, "users/me/muted", :user, {:response => :collection}) do |h|
63 | h["data"][0]["you_muted"] = true
64 | end %>
65 |
66 | ## Retrieve muted User IDs for multiple Users
67 |
68 | Returns a list of muted User ids for each User id requested. At most 200 User ids can be requested.
69 |
70 | <%= endpoint "GET", "users/muted/ids", "App" %>
71 |
72 | <%= query_params [
73 | ["ids","A comma separated list of User ids to retrieve muted User ids for."]
74 | ]%>
75 |
76 | #### Example
77 |
78 | <%= curl_example(:get, "users/muted/ids?ids=1,2", {
79 | "1" => ["3", "29"],
80 | "2" => []
81 | }, {:token => ""}) %>
82 |
--------------------------------------------------------------------------------
/content/reference/resources/channel/lookup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Channel Lookup"
3 | ---
4 |
5 | # Lookup
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve a Channel
11 |
12 | Returns a specific [Channel](/reference/resources/channel/).
13 |
14 | <%= general_params_note_for "channel" %>
15 |
16 | <%= endpoint "GET", "channels/[channel_id]", "Any", "public_messages or messages"%>
17 |
18 | <%= url_params [
19 | ["channel_id", "The id of the Channel to retrieve."]
20 | ]%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:get, "channels/1", :channel) %>
25 |
26 | ## Retrieve multiple Channels
27 | Returns multiple Channels requested by id. At most 200 channels can be requested. Channels which do not exist or which the requesting user does not have authorization to view will not be returned.
28 |
29 | <%= general_params_note_for "channel" %>
30 |
31 | <%= endpoint "GET", "channels", "Any" %>
32 |
33 | <%= query_params [
34 | ["ids", "A comma separated list of ids of Channels to retrieve."]
35 | ]%>
36 |
37 | #### Example
38 |
39 | In the following example, Channel 6502 is omitted because it doesn't exist or we don't have permission to view it.
40 |
41 | <%= curl_example(:get, "channels?ids=1,2,6502", :channel, {:response => :collection}) do |h|
42 | second = h["data"][0].clone()
43 | second["id"] = "2"
44 | h["data"].unshift(second)
45 | end %>
46 |
47 | ## Retrieve my Channels
48 | Returns a stream of all Channels the current user has created.
49 |
50 | <%= general_params_note_for "channel" %>
51 |
52 | <%= pagination_note %>
53 |
54 | <%= endpoint "GET", "users/me/channels", "User", "public_messages or messages"%>
55 |
56 | #### Example
57 |
58 | <%= curl_example(:get, "users/me/channels", :channel, {:response => :paginated}) %>
59 |
60 | ## Retrieve number of unread PM Channels
61 | Returns the current number of `net.app.core.pm` Channels where `has_unread: true` for the current user.
62 |
63 | <%= endpoint "GET", "users/me/channels/pm/num_unread", "User", "messages"%>
64 |
65 | #### Example
66 |
67 | <%= curl_example(:get, "users/me/channels/pm/num_unread", 5) %>
68 |
69 | ## Retrieve number of unread Broadcast Channels
70 | Returns the current number of `net.app.core.broadcast` Channels where `has_unread: true` for the current user.
71 |
72 | <%= endpoint "GET", "users/me/channels/broadcast/num_unread", "User", "messages"%>
73 |
74 | #### Example
75 |
76 | <%= curl_example(:get, "users/me/channels/broadcast/num_unread", 3) %>
77 |
78 |
79 | ## Mark all Broadcast Channels as read
80 | Mark all `net.app.core.broadcast` Channels as read for the current user.
81 |
82 | <%= endpoint "DELETE", "users/me/channels/broadcast/num_unread", "User", "messages"%>
83 |
84 | #### Example
85 |
86 | <%= curl_example(:delete, "users/me/channels/broadcast/num_unread", 0) %>
87 |
--------------------------------------------------------------------------------
/content/reference/resources/post/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Post Lifecycle"
3 | ---
4 |
5 | # Post Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Create a Post
11 |
12 | Create a new Post object. Mentions and hashtags will be parsed out of the post text, as will bare URLs.
13 |
14 | You can also create a Post by sending JSON in the HTTP post body that matches the post schema with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `text`, `reply_to`, `machine_only`, `annotations` and `entities`. To create complex posts (including [machine only posts](/reference/resources/post/#machine-only-posts)), you must use the JSON interface. See the [JSON example](#json-example) below. If you would like to specify your own entities, please refer to the [user specified entities](/reference/meta/entities/#user-specified-entities) documentation.
15 |
16 | If you want to test how your text will be processed you can use the [text processor](/reference/resources/text-processor).
17 |
18 | *You cannot reply to a repost. Please reply to the parent Post.*
19 |
20 | <%= general_params_note_for "post" %>
21 |
22 | <%= endpoint "POST", "posts", "User", "write_post" %>
23 |
24 | <%= post_params [
25 | ["text", "The raw text of the post."],
26 | ["reply_to", "(Optional) The id of the Post that this new Post is replying to."]
27 | ]%>
28 |
29 | #### Example
30 |
31 | <% text = get_hash(:post)["text"] %>
32 | <%= curl_example(:post, "posts", :post, {:data => {"text" => text}, :content_type => nil}) %>
33 |
34 | #### Example (JSON Data)
35 |
36 | <% data = {
37 | "text" => text,
38 | "annotations" => [{
39 | "type" => "net.app.core.geolocation",
40 | "value" => {
41 | "latitude" => 74.0064,
42 | "longitude" => 40.7142
43 | }
44 | }]
45 | } %>
46 | <%= curl_example(:post, "posts?include_post_annoations=1", :post, {:data => data}) do |h|
47 | h["data"]["annotations"] = data["annotations"]
48 | end %>
49 |
50 | ## Delete a Post
51 |
52 | Delete a Post. The current user must be the same user who created the Post. It returns the deleted Post on success.
53 |
54 | <%= general_params_note_for "post" %>
55 |
56 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
57 |
58 | <%= endpoint "DELETE", "posts/[post_id]", "User", "write_post" %>
59 |
60 | <%= url_params [
61 | ["post_id", "The id of the Post to delete."]
62 | ]%>
63 |
64 | #### Example
65 |
66 | <%= curl_example(:delete, "posts/#{get_id(:post)}", :post) do |h|
67 | h["data"]["is_deleted"] = true
68 | h["data"].delete("text")
69 | h["data"].delete("html")
70 | h["data"]["entities"].each { |k, v| h["data"]["entities"][k] = []}
71 | end %>
72 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/file.md:
--------------------------------------------------------------------------------
1 |
73 |
--------------------------------------------------------------------------------
/content/reference/resources/file/content.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "File Content"
3 | ---
4 |
5 | # Content
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Get File content
11 |
12 | Get the content for a complete File.
13 |
14 | This endpoint will return a 302 Redirect to a temporary URL for the content of this file. This endpoint is useful for fetching private content from a file.
15 |
16 | <%= endpoint "GET", "files/[file_id]/content", "User" %>
17 |
18 | <%= file_token_reminder %>
19 |
20 | <%= url_params [
21 | ["file_id", "The id of the File to retrieve content for."]
22 | ]%>
23 |
24 | ## Set File content
25 |
26 | Set the content for an incomplete File. The content type for this request must be the content type of the file you are uploading. This endpoint can optionally accept a header field `x-adn-filename` to set the File's name.
27 |
28 | This endpoint could return a `507 Insufficient Storage` error if the user doesn't have enough space for this file. For more information, see [file storage limits](/reference/resources/file/#limits).
29 |
30 | When successful, this endpoint will return a `204 No Content` response.
31 |
32 | <%= endpoint "PUT", "files/[file_id]/content", "User" %>
33 |
34 | <%= file_token_reminder %>
35 |
36 | <%= url_params [
37 | ["file_id", "The id of the File to set content for."]
38 | ]%>
39 |
40 | #### Example
41 |
42 | <%= curl_example(:put, "files/1/content", "204 No Content", {
43 | :content_type => "image/png",
44 | :data_binary => "@filename.png",
45 | :response => :raw
46 | }) %>
47 |
48 | ## Get Derived File content
49 |
50 | Get the content for a derived file of a complete File.
51 |
52 | This endpoint will return a 302 Redirect to a temporary URL for the content of this derived file.
53 |
54 | <%= endpoint "GET", "files/[file_id]/content/[derived_file_key]", "User" %>
55 |
56 | <%= file_token_reminder %>
57 |
58 | <%= url_params [
59 | ["file_id", "The id of the File to retrieve content for."],
60 | ["derived_file_key", "The key identifying the derived file you want the content for."]
61 | ]%>
62 |
63 | ## Set Derived File content
64 |
65 | Set the content for a derived file of an incomplete File. The content type for this request must be the content type of the file you are uploading. This endpoint can optionally accept a header field `x-adn-filename` to set the Derived File's name.
66 |
67 | This endpoint could return a `507 Insufficient Storage` error if the user doesn't have enough space for this derived file. For more information, see [file storage limits](/reference/resources/file/#limits).
68 |
69 | <%= endpoint "PUT", "files/[file_id]/content/[derived_file_key]", "User" %>
70 |
71 | <%= file_token_reminder %>
72 |
73 | <%= url_params [
74 | ["file_id", "The id of the File to set content for."],
75 | ["derived_file_key", "The key identifying the derived file you want to create."]
76 | ]%>
77 |
78 | #### Example
79 |
80 | <%= curl_example(:put, "files/1/content/thumbnail_png", "204 No Content", {
81 | :content_type => "image/png",
82 | :data_binary => "@filename.png",
83 | :response => :raw
84 | }) %>
85 |
--------------------------------------------------------------------------------
/content/reference/other/web-intents.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Web Intents"
3 | ---
4 |
5 | # Web Intents
6 |
7 | * TOC
8 | {:toc}
9 |
10 | Web intents are an easy way to integrate with App.net; you don't even need to use Javascript. Intents in their most basic form are just carefully constructed URLs. By clicking on an intent link, a user will be taken to a page on App.net with a prompt to carry out an action, such as creating a post. If the user is not logged in to App.net, she/he will first authenticate before being presented with the action dialog.
11 |
12 |
13 |
14 |
If you just want a simple follow or share button you can use button builder instead. We've also open sourced the buttons so that you could host them your self. Checkout the github repo for more information on how to do that.
15 |
16 |
17 | ## The Post Intent
18 |
19 | The post intent allows you to create a link that will present the user with a post creation box and any pre-filled text that you may have supplied.
20 |
21 | The base URL for this intent is `https://alpha.app.net/intent/post/`.
22 |
23 | You may optionally prepopulate the post creation box by supplying a `text` query parameter to the URL.
24 |
25 | For example, this URL `https://alpha.app.net/intent/post/?text=%40adn%20When%20is%20the%20next%20meetup%3F` will create a post that reads:
26 |
27 | > @adn When is the next meetup?
28 |
29 | At this point the end user will be able to edit and then submit the post.
30 |
31 | There is a second optional parameter: `url`. This allows you to automatically appended a URL to a post.
32 |
33 | For example, this URL: `https://alpha.app.net/intent/post/?text=%40adn%20Does%20this%20place%20work%3F&url=https%3A%2F%2Fmaps.google.com%2Fmaps%3Fq%3Dpublic%2Bhouse%2Bsf%26fb%3D1%26gl%3Dus%26hq%3Dpublic%2Bhouse%26hnear%3D0x80859a6d00690021%3A0x4a501367f076adff%2CSan%2BFrancisco%2C%2BCA%26cid%3D0%2C0%2C2651066427117992613%26t%3Dm%26z%3D16%26iwloc%3DA` will create a post that reads:
34 |
35 | > @adn Does this place work? https://maps.google.com/maps?q=public+…
36 |
37 | You'll notice that the displayed URL is automatically truncated to 40 chars. The full URL is included though. If your URL is less then 40 chars it will be included as is.
38 |
39 |
40 | ## The Follow Intent
41 |
42 | The follow intent is an easy way to link to a page on App.net that will present the user with an opportunity to follow a selected user.
43 |
44 | The base URL for this intent is `https://alpha.app.net/intent/follow/`.
45 |
46 | You must include a user that is the intended target of the follow action. To do this include a `user_id` query parameter in the URL. The `user_id` can be a username prepended by a @, like @adn, or it can be the numeric user_id, like 136.
47 |
48 | For example, this URL `https://alpha.app.net/intent/follow/?user_id=136` will show page where the user can choose to follow the user @adn.
49 |
--------------------------------------------------------------------------------
/content/reference/resources/post/streams.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Post Streams"
3 | ---
4 |
5 | # Post Streams
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Retrieve the Global stream
11 |
12 | Return the 20 most recent [Posts](/reference/resources/post/) from the Global stream.
13 |
14 | <%= general_params_note_for "post" %>
15 |
16 | <%= pagination_note %>
17 |
18 | <%= endpoint "GET", "posts/stream/global", "None" %>
19 |
20 | #### Example
21 |
22 | <%= curl_example(:get, "posts/stream/global", :post, {:response => :paginated}) %>
23 |
24 | ## Retrieve Posts created by a User
25 |
26 | Get the most recent [Posts](/reference/resources/post/) created by a specific [User](/reference/resources/user/) in reverse post order.
27 |
28 | <%= general_params_note_for "post" %>
29 |
30 | <%= pagination_note %>
31 |
32 | <%= endpoint "GET", "users/[user_id]/posts", "None" %>
33 |
34 | <%= url_params [
35 | ["user_id", "The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
36 | ]%>
37 |
38 | #### Example
39 |
40 | <%= curl_example(:get, "users/#{get_id(:user)}/posts", :post, {:response => :paginated}) %>
41 |
42 | ## Retrieve Posts mentioning a User
43 |
44 | Get the most recent [Posts](/reference/resources/post/) mentioning by a specific [User](/reference/resources/user/) in reverse post order.
45 |
46 | <%= general_params_note_for "post" %>
47 |
48 | <%= pagination_note %>
49 |
50 | <%= endpoint "GET", "users/[user_id]/mentions", "Any" %>
51 |
52 | <%= url_params [
53 | ["user_id", "The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
54 | ]%>
55 |
56 | #### Example
57 |
58 | <%= curl_example(:get, "users/2/mentions", :post, {:response => :paginated}) %>
59 |
60 | ## Retrieve a User's personalized stream
61 |
62 | Return the 20 most recent [Posts](/reference/resources/post/) from the current User and the Users they follow.
63 |
64 | <%= general_params_note_for "post" %>
65 |
66 | <%= stream_facet_note %>
67 |
68 | <%= pagination_note %>
69 |
70 | <%= endpoint "GET", "posts/stream", "User", "stream" %>
71 |
72 | #### Example
73 |
74 | <%= curl_example(:get, "posts/stream", :post, {:response => :paginated}) %>
75 |
76 | ## Retrieve a User's unified stream
77 |
78 | Return the 20 most recent [Posts](/reference/resources/post/) from the current user's [personalized stream](#retrieve-a-users-personalized-stream) and [mentions stream](#retrieve-posts-mentioning-a-user) merged into one stream.
79 |
80 | <%= general_params_note_for "post" %>
81 |
82 | <%= pagination_note %>
83 |
84 | <%= stream_facet_note %>
85 |
86 | <%= endpoint "GET", "posts/stream/unified", "User", "stream" %>
87 |
88 | #### Example
89 |
90 | <%= curl_example(:get, "posts/stream/unified", :post, {:response => :paginated}) %>
91 |
92 | ## Retrieve tagged Posts
93 |
94 | Return the 20 most recent [Posts](/reference/resources/post/) for a specific hashtag.
95 |
96 | <%= general_params_note_for "post" %>
97 |
98 | <%= pagination_note %>
99 |
100 | <%= endpoint "GET", "posts/tag/[hashtag]", "None" %>
101 |
102 | #### Example
103 |
104 | <%= curl_example(:get, "posts/tag/adnhack", :post, {:response => :paginated}) %>
105 |
--------------------------------------------------------------------------------
/content/reference/make-request/rate-limits.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Rate Limits"
3 | ---
4 |
5 | # Rate Limits
6 |
7 | * TOC
8 | {:toc}
9 |
10 | Fundamental limits of server resources and network infrastructure make it necessary for us to limit the rate at which we handle requests. By enforcing request rate limits, we make it feasible to fairly and evenly distribute our capacity amongst our users and prevent apps from monopolizing these resources.
11 |
12 | ## Enforcement
13 |
14 | Any request, authorized or unauthorized, may be subject to multiple rate limits. At present, authorized calls are limited per access token, while unauthorized calls are limited per IP address. When more than one limit applies to a request, the request will apply against each of those limits, but information will be returned on only the most restrictive of those limits.
15 |
16 | ## Response Headers
17 |
18 | The following sample shows a set of three headers which might be returned with a response to a call to the API.
19 |
20 | X-RateLimit-Remaining: 4959
21 | X-RateLimit-Limit: 5000
22 | X-RateLimit-Reset: 3600
23 |
24 | The first header, `X-RateLimit-Remaining`, indicates the total number of requests remaining for this cycle (4959). `X-RateLimit-Limit` indicates the total capacity (5000). `X-RateLimit-Reset` gives the number of seconds until the remaining number of requests will be reset to the capacity; in this case, `X-RateLimit-Remaining` will be reset to 5000 requests in 3600 seconds, irrespective of how many additional requests are made between now and then.
25 |
26 | ## Exceeding Limits
27 |
28 | Should your request exceed any applicable rate limits, we will return a status code `429` (Too many requests). We ask that any app which is accessing our API respect this response code. The `Retry-After` header will contain the number of seconds before another request of this type can be made -- if your request receives a `429` code, your application should wait until the `Retry-After` period has elapsed before attempting the same kind of request.
29 |
30 | ## Limits
31 |
32 | At present, these are the limit values we use:
33 |
34 | ### Authenticated Requests (per token)
35 |
36 |
37 |
38 |
39 |
Type
40 |
Limit
41 |
Period
42 |
Notes
43 |
44 |
45 |
46 |
47 |
Global
48 |
5000
49 |
1 hour (3600 seconds)
50 |
Affects all authenticated endpoints, even if other limits apply as well.
81 |
--------------------------------------------------------------------------------
/content/reference/resources/user/blocking.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Blocking"
3 | ---
4 |
5 | # Blocking
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Block a User
11 |
12 | Block a user from seeing your App.net content. This means the user will not be able to see, star, reply to, or repost your content. This user will also effectively be muted for you. This will automatically unfollow both users from each other. A user may be able to tell if they've been blocked by a user. For instance if @mthurman blocks @berg and @berg logs out of alpha.app.net, he could see @mthurman's profile.
13 |
14 | In most cases, [muting a user](/reference/resources/user/muting/#mute-a-user) is probably sufficient since that hides all of a user's content from you. If a user is aggressively reposting or starring your content, blocking them will prevent them from interacting with your content at all.
15 |
16 | <%= general_params_note_for "user" %>
17 |
18 | <%= endpoint "POST", "users/[user_id]/block", "User", "follow" %>
19 |
20 | <%= url_params [
21 | ["user_id","The id of the User to block. You can also specify @username as a user_id."]
22 | ]%>
23 |
24 | #### Example
25 |
26 | <%= curl_example(:post, "users/#{get_id(:user)}/block", :user) do |h|
27 | h["data"]["you_blocked"] = true
28 | h["data"]["you_follow"] = false
29 | end %>
30 |
31 | ## Unblock a User
32 |
33 | Allow a blocked user to interact with my content.
34 |
35 | <%= general_params_note_for "user" %>
36 |
37 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
38 |
39 | <%= endpoint "DELETE", "users/[user_id]/block", "User", "follow" %>
40 |
41 | <%= url_params [
42 | ["user_id","The id of the User to block. You can also specify @username as a user_id."]
43 | ]%>
44 |
45 | #### Example
46 |
47 | <%= curl_example(:delete, "users/#{get_id(:user)}/block", :user) do |h|
48 | h["data"]["you_blocked"] = false
49 | h["data"]["you_follow"] = false
50 | end %>
51 |
52 | ## List blocked Users
53 |
54 | Retrieve a list of blocked users.
55 |
56 | <%= general_params_note_for "user" %>
57 |
58 | <%= endpoint "GET", "users/[user_id]/blocked", "Any" %>
59 |
60 | <%= url_params [
61 | ["user_id",'The id of the user to retrieve a list of muted users for. If requested with a user token you can request blocked users for the current user by using me as the user id. If requested with an app token you can request blocked users for any user that has authorized your app.']
62 | ]%>
63 |
64 | #### Example
65 |
66 | <%= curl_example(:get, "users/me/blocked", :user, {:response => :collection}) do |h|
67 | h["data"][0]["you_blocked"] = true
68 | h["data"][0]["you_follow"] = false
69 | end %>
70 |
71 | ## Retrieve blocked User IDs for multiple Users
72 |
73 | Returns a list of blocked User ids for each User id requested. At most 200 User ids can be requested.
74 |
75 | <%= endpoint "GET", "users/blocked/ids", "App" %>
76 |
77 | <%= query_params [
78 | ["ids","A comma separated list of User ids to retrieve blocked User ids for."]
79 | ]%>
80 |
81 | #### Example
82 |
83 | <%= curl_example(:get, "users/blocked/ids?ids=1,2", {
84 | "1" => ["3", "29"],
85 | "2" => []
86 | }, {:token => ""}) %>
87 |
--------------------------------------------------------------------------------
/content/reference/make-request/migrations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Migrations"
3 | ---
4 |
5 | # Migrations
6 |
7 | * TOC
8 | {:toc}
9 |
10 | We reserve the right to make incremental changes to the API as we deem necessary. In order to make it possible to change the API but still support legacy applications, we will make use of migrations. Migrations are a per-app feature that developers may toggle for their own apps from the time that the old behavior is deprecated until the time that it has reached the end of its life (EOL). Once the EOL date is reached, the migration will be enabled for all apps with no legacy mode available.
11 |
12 | ## Accessing Migration Data
13 |
14 | We offer a single toggle for each migration and app that will globally turn the migration on (current mode) or off (legacy mode) for that app as well as a per-call header mechanism that overrides the global behavior.
15 |
16 | ### Global Toggle
17 |
18 | You can toggle the global migration behavior of your apps by editing your apps listed at [https://account.app.net/developer/apps/](https://account.app.net/developer/apps/).
19 |
20 | By default, new apps will come with all existing migrations toggled to "Current" mode. This reflects the fact that support for legacy mode will eventually be removed. However, any migrations that are released after the app is created will be initially toggled to "Legacy" mode, so app developers can expect that the API behavior will not unexpectedly change for existing apps.
21 |
22 | ### Per-call Toggle
23 | In addition to using the edit app toggles, we offer the `X-ADN-Migration-Overrides` header as a way for developers to override migration behavior on a per-call basis. This header should contain a **query-string encoded** list of valid [migration keys](#current-migrations) and values (0 or 1). For example, providing `X-ADN-Migration-Overrides: foo=0` would disable the migration named `foo`. We expect that some apps may be distributed in such a way that some users may be running old versions while others are running newer versions, so this override header may make it easier to adopt new functionality without causing regressions. As with the toggle, though, migration override keys cannot be used past their EOL dates. Also, `X-ADN-Migration-Overrides` is whitelisted for CORS, so we expect that it should be usable in all contexts.
24 |
25 | ### Migration Response Header
26 | All calls to our endpoints will return `X-ADN-Migrations-Enabled`, a query-string encoded list of migration keys that are enabled for that particular API call. This list will take into account globally toggled migrations as well as those enabled by `X-ADN-Migration-Overrides`.
27 |
28 | ### Using Migrations with JSONP
29 | For JSONP requests we offer the ability to override the default migration behavior on a per-call basis. To do this, add a list of valid [migration keys](#current-migrations) and values (0 or 1) to the query string. For example, `https://alpha-api.app.net/stream/0/posts/stream/global?callback=json_callback&foo=0`
30 |
31 | **Toggling migrations with the query string is ONLY available for JSONP requests.** Use the header mechanism for all other requests.
32 |
33 | ## Current Migrations
34 |
35 |
36 |
37 |
38 |
Key
39 |
Migration (name)
40 |
Description
41 |
End-Of-Life Date
42 |
43 |
44 |
45 |
46 |
47 |
48 |
There are no active migrations.
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/content/reference/resources/interaction/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Interactions"
3 | ---
4 |
5 | # Interactions
6 |
7 | * TOC
8 | {:toc}
9 |
10 | Interactions are objects that represent users taking certain actions on App.net. Interactions are structured to form a sentence like: User X took action Y on object Z. If multiple users take the same action (e.g. multiple users reply to one post) within a set time window those events will be combined into a single Interaction.
11 |
12 | > The `objects` list of an Interaction will vary based on the `action`
13 |
14 | (Example) @dalton and @berg reposted post 1:
15 |
16 | <%= json_output(:repost_interaction) %>
17 |
18 | (Example) @berg started following @dalton:
19 |
20 | <%= json(:follow_interaction) %>
21 |
22 | ## Interactions Fields
23 |
24 |
25 |
26 |
27 |
Field
28 |
Type
29 |
Description
30 |
31 |
32 |
33 |
34 |
action
35 |
string
36 |
What users did. Currently one of follow, reply, repost, star, welcome, broadcast_create, broadcast_subscribe, or broadcast_unsubscribe.
37 |
38 |
39 |
event_date
40 |
string
41 |
The time of the most recent interaction occurred at in ISO 8601 format.
42 |
43 |
44 |
objects
45 |
list
46 |
users took action on. These objects will be Users if action=follow. For star, repost, reply these objects will be Posts. For broadcast_create, broadcast_subscribe, broadcast_subscribe these will be channels. For welcome this will be empty.
47 |
48 |
49 |
users
50 |
list
51 |
A list of User objects that took action on objects.
52 |
53 |
54 |
55 |
56 | ## List User interactions with me
57 |
58 | List all the [Interactions](/reference/resources/interaction/) other users have had with me.
59 |
60 | <%= pagination_note %>
61 |
62 | > You can only request this list for the current user.
63 |
64 |
65 | > Although this endpoint supports paging, a user's Interactions stream is continuously rebuilt as new actions in the system occur, so developers should generally plan to refetch the stream whenever switching to display it as Interactions may have shifted their position, with users being added or removed. If you need to keep track of activity in a more precise manner, you should using the [Streaming API](/reference/resources/app-stream/) to monitor the global feed for relevant activity.
66 |
67 | This endpoint accepts the `interaction_actions` as a query string parameter whose value is a comma separated list of actions you're interested in. For instance, if you're only interested in repost and follow interactions you could request `stream/0/users/me/interactions?interaction_actions=repost,follow`.
68 |
69 | <%= endpoint "GET", "users/me/interactions", "User" %>
70 |
71 | #### Example
72 |
73 | <%= curl_example(:get, "users/me/interactions", :repost_interaction, {:response => :paginated}) do |h|
74 | h["data"][0]["pagination_id"] = "10"
75 | end %>
76 |
--------------------------------------------------------------------------------
/content/reference/resources/channel/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Channel Lifecycle"
3 | ---
4 |
5 | # Channel Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Create a Channel
11 |
12 | Create a new [Channel](/reference/resources/channel/).
13 |
14 | Send a JSON document that matches the [Channel schema](/reference/resources/channel/) with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `readers`, `writers`, `annotations`, and `type`. The owner will be auto-subscribed to this channel.
15 |
16 | ### Creating a PM Channel
17 |
18 | [PM Channels](/reference/resources/channel/#private-message) (channels of type `net.app.core.pm`) cannot be directly created. Instead they are created for you as necessary when sending a [Message](/reference/resources/message/) using `pm` as a `channel_id`. For more information, see the [Create a Message](/reference/resources/message/lifecycle/#create-a-message) endpoint.
19 |
20 | <%= general_params_note_for "channel" %>
21 |
22 | <%= endpoint "POST", "channels", "User", "public_messages or messages"%>
23 |
24 | ### Example
25 |
26 | <% data = {
27 | "type" => "com.example.channel",
28 | "writers" => {
29 | "user_ids" => ["@berg", "1"]
30 | }
31 | } %>
32 | <%= curl_example(:post, "channels", :channel, {:data => data}) do |h|
33 | h["data"]["id"] = "2"
34 | h["data"]["readers"]["public"] = false
35 | h["data"]["writers"]["user_ids"] = ["1", "2"]
36 | h["data"].delete("recent_message_id")
37 | h["data"].delete("recent_message")
38 | end %>
39 |
40 | ## Update a Channel
41 |
42 | Updates a specific [Channel](/reference/resources/channel/) object. You can update a channel by PUTing an object that matches the [Channel schema](/reference/resources/channel/) with an HTTP header of `Content-Type: application/json`. The only keys that can be updated are `annotations`, `readers`, and `writers` (and the ACLs can only be updated if `immutable=false`). The `you_can_edit` property tells you if you are allowed to update a channel. Currently, only the Channel owner can edit a channel.
43 |
44 | If you want to add or update a Channel's annotations, you may include the optional `annotations` key and pass in the annotations that are changing.
45 |
46 | This endpoint currently works identically for the `PUT` and `PATCH` HTTP methods.
47 |
48 | <%= general_params_note_for "channel" %>
49 |
50 | <%= endpoint "PUT", "channels/[channel_id]", "User", "public_messages or messages"%>
51 |
52 | <%= url_params [
53 | ["channel_id", "The id of the Channel to update."]
54 | ]%>
55 |
56 | #### Example
57 |
58 | <%= curl_example(:put, "channels/1", :channel, {:data => {"readers" => {"public" => true}}}) %>
59 |
60 | ## Deactivate a Channel
61 |
62 | Mark a channel as inactive. This **does not** delete the contents of the Channel. It prevents new messages from being added to the channel and unsubscribes all users from the Channel. This channel will be hidden unless it is explicitly requested by id or the `include_inactive=1` parameter is used. This is irreversible.
63 |
64 | The current user must be the same user who created the Channel. *Editors cannot delete a channel*
65 |
66 | *net.app.core.pm* channels cannot be marked as inactive.
67 |
68 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
69 |
70 | <%= general_params_note_for "channel" %>
71 |
72 | <%= endpoint "DELETE", "channels/[channel_id]", "User" %>
73 |
74 | <%= url_params [
75 | ["channel_id", "The id of the Channel to delete."]
76 | ]%>
77 |
78 | ### Example
79 |
80 | <%= curl_example(:delete, "channels/1", :channel) do |h|
81 | h["data"]["is_inactive"] = true
82 | h["data"]["counts"]["subscribers"] = 0
83 | h["you_subscribed"] = false
84 | end %>
85 |
--------------------------------------------------------------------------------
/config.yaml:
--------------------------------------------------------------------------------
1 | # Nanoc really doesn't have any sense of an environment
2 | # Instead we have a different config file for each enviroment
3 | # If you make a change to one config file, you need to make a change to all of them
4 |
5 |
6 | # A list of file extensions that nanoc will consider to be textual rather than
7 | # binary. If an item with an extension not in this list is found, the file
8 | # will be considered as binary.
9 | text_extensions: [ 'coffee', 'css', 'erb', 'haml', 'handlebars', 'hb', 'htm', 'html', 'js', 'less', 'markdown', 'md', 'ms', 'mustache', 'php', 'rb', 'sass', 'scss', 'txt', 'xhtml', 'xml' ]
10 |
11 | # The path to the directory where all generated files will be written to. This
12 | # can be an absolute path starting with a slash, but it can also be path
13 | # relative to the site directory.
14 | output_dir: output
15 |
16 | # A list of index filenames, i.e. names of files that will be served by a web
17 | # server when a directory is requested. Usually, index files are named
18 | # “index.html”, but depending on the web server, this may be something else,
19 | # such as “default.htm”. This list is used by nanoc to generate pretty URLs.
20 | index_filenames: [ 'index.html' ]
21 |
22 | # Whether or not to generate a diff of the compiled content when compiling a
23 | # site. The diff will contain the differences between the compiled content
24 | # before and after the last site compilation.
25 | enable_output_diff: false
26 |
27 | prune:
28 | # Whether to automatically remove files not managed by nanoc from the output
29 | # directory. For safety reasons, this is turned off by default.
30 | auto_prune: false
31 |
32 | # Which files and directories you want to exclude from pruning. If you version
33 | # your output directory, you should probably exclude VCS directories such as
34 | # .git, .svn etc.
35 | exclude: [ '.git', '.hg', '.svn', 'CVS' ]
36 |
37 | # The data sources where nanoc loads its data from. This is an array of
38 | # hashes; each array element represents a single data source. By default,
39 | # there is only a single data source that reads data from the “content/” and
40 | # “layout/” directories in the site directory.
41 | data_sources:
42 | -
43 | # The type is the identifier of the data source. By default, this will be
44 | # `filesystem_unified`.
45 | type: filesystem_unified
46 |
47 | # The path where items should be mounted (comparable to mount points in
48 | # Unix-like systems). This is “/” by default, meaning that items will have
49 | # “/” prefixed to their identifiers. If the items root were “/en/”
50 | # instead, an item at content/about.html would have an identifier of
51 | # “/en/about/” instead of just “/about/”.
52 | items_root: /
53 |
54 | # The path where layouts should be mounted. The layouts root behaves the
55 | # same as the items root, but applies to layouts rather than items.
56 | layouts_root: /
57 |
58 | # Whether to allow periods in identifiers. When turned off, everything
59 | # past the first period is considered to be the extension, and when
60 | # turned on, only the characters past the last period are considered to
61 | # be the extension. For example, a file named “content/about.html.erb”
62 | # will have the identifier “/about/” when turned off, but when turned on
63 | # it will become “/about.html/” instead.
64 | allow_periods_in_identifiers: false
65 |
66 | -
67 | type: static
68 | items_root: /static
69 |
70 | redirects:
71 | -
72 | from: /docs/basics/messaging/
73 | to: /docs/guides/messaging/
74 | -
75 | from: /docs/resources/stream/(.*)
76 | to: /reference/resources/app-stream/$1
77 | -
78 | from: /docs/(resources|authentication|meta|other)/(.*)
79 | to: /reference/$1/$2
80 | -
81 | from: /docs/basics/(.*)
82 | to: /reference/make-request/$1
83 | -
84 | from: /docs/guides/getting-started/
85 | to: /
86 |
--------------------------------------------------------------------------------
/static/css/pygments.css:
--------------------------------------------------------------------------------
1 | pre code .hll { background-color: #ffffcc }
2 | pre code .c { color: #408080; font-style: italic } /* Comment */
3 | pre code .err { border: 1px solid #FF0000 } /* Error */
4 | pre code .k { color: #008000; font-weight: bold } /* Keyword */
5 | pre code .o { color: #666666 } /* Operator */
6 | pre code .cm { color: #408080; font-style: italic } /* Comment.Multiline */
7 | pre code .cp { color: #BC7A00 } /* Comment.Preproc */
8 | pre code .c1 { color: #408080; font-style: italic } /* Comment.Single */
9 | pre code .cs { color: #408080; font-style: italic } /* Comment.Special */
10 | pre code .gd { color: #A00000 } /* Generic.Deleted */
11 | pre code .ge { font-style: italic } /* Generic.Emph */
12 | pre code .gr { color: #FF0000 } /* Generic.Error */
13 | pre code .gh { color: #000080; font-weight: bold } /* Generic.Heading */
14 | pre code .gi { color: #00A000 } /* Generic.Inserted */
15 | pre code .go { color: #808080 } /* Generic.Output */
16 | pre code .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
17 | pre code .gs { font-weight: bold } /* Generic.Strong */
18 | pre code .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
19 | pre code .gt { color: #0040D0 } /* Generic.Traceback */
20 | pre code .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
21 | pre code .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
22 | pre code .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
23 | pre code .kp { color: #008000 } /* Keyword.Pseudo */
24 | pre code .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
25 | pre code .kt { color: #B00040 } /* Keyword.Type */
26 | pre code .m { color: #666666 } /* Literal.Number */
27 | pre code .s { color: #BA2121 } /* Literal.String */
28 | pre code .na { color: #7D9029 } /* Name.Attribute */
29 | pre code .nb { color: #008000 } /* Name.Builtin */
30 | pre code .nc { color: #0000FF; font-weight: bold } /* Name.Class */
31 | pre code .no { color: #880000 } /* Name.Constant */
32 | pre code .nd { color: #AA22FF } /* Name.Decorator */
33 | pre code .ni { color: #999999; font-weight: bold } /* Name.Entity */
34 | pre code .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
35 | pre code .nf { color: #0000FF } /* Name.Function */
36 | pre code .nl { color: #A0A000 } /* Name.Label */
37 | pre code .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
38 | pre code .nt { color: #008000; font-weight: bold } /* Name.Tag */
39 | pre code .nv { color: #19177C } /* Name.Variable */
40 | pre code .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
41 | pre code .w { color: #bbbbbb } /* Text.Whitespace */
42 | pre code .mf { color: #666666 } /* Literal.Number.Float */
43 | pre code .mh { color: #666666 } /* Literal.Number.Hex */
44 | pre code .mi { color: #666666 } /* Literal.Number.Integer */
45 | pre code .mo { color: #666666 } /* Literal.Number.Oct */
46 | pre code .sb { color: #BA2121 } /* Literal.String.Backtick */
47 | pre code .sc { color: #BA2121 } /* Literal.String.Char */
48 | pre code .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
49 | pre code .s2 { color: #BA2121 } /* Literal.String.Double */
50 | pre code .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
51 | pre code .sh { color: #BA2121 } /* Literal.String.Heredoc */
52 | pre code .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
53 | pre code .sx { color: #008000 } /* Literal.String.Other */
54 | pre code .sr { color: #BB6688 } /* Literal.String.Regex */
55 | pre code .s1 { color: #BA2121 } /* Literal.String.Single */
56 | pre code .ss { color: #19177C } /* Literal.String.Symbol */
57 | pre code .bp { color: #008000 } /* Name.Builtin.Pseudo */
58 | pre code .vc { color: #19177C } /* Name.Variable.Class */
59 | pre code .vg { color: #19177C } /* Name.Variable.Global */
60 | pre code .vi { color: #19177C } /* Name.Variable.Instance */
61 | pre code .il { color: #666666 } /* Literal.Number.Integer.Long */
62 |
--------------------------------------------------------------------------------
/content/reference/resources/user/following.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "User Following"
3 | ---
4 |
5 | # Following
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Follow a User
11 |
12 | Returns the User object of the user being followed.
13 |
14 | <%= general_params_note_for "user" %>
15 |
16 | <%= endpoint "POST", "users/[user_id]/follow", "User", "follow" %>
17 |
18 | <%= url_params [
19 | ["user_id","The user id to be followed. You can also specify @username as a user_id."]
20 | ]%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:post, "users/#{get_id(:user)}/follow", :user) do |h|
25 | h["data"]["you_follow"] = true
26 | end %>
27 |
28 | ## Unfollow a User
29 |
30 | Returns the User object of the user being unfollowed.
31 |
32 | <%= general_params_note_for "user" %>
33 |
34 | *Remember, access tokens cannot be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
35 |
36 | <%= endpoint "DELETE", "users/[user_id]/follow", "User", "follow" %>
37 |
38 | <%= url_params [
39 | ["user_id","The user id to stop following. You can also specify @username as a user_id."]
40 | ]%>
41 |
42 | #### Example
43 |
44 | <%= curl_example(:delete, "users/#{get_id(:user)}/follow", :user) do |h|
45 | h["data"]["you_follow"] = false
46 | end %>
47 |
48 | ## List users a user is following
49 |
50 | Returns a list of User objects the specified user is following.
51 |
52 | <%= general_params_note_for "user" %>
53 |
54 | <%= pagination_note %>
55 |
56 | <%= endpoint "GET", "users/[user_id]/following", "Any" %>
57 |
58 | <%= url_params [
59 | ["user_id","The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
60 | ]%>
61 |
62 | #### Example
63 |
64 | <%= curl_example(:get, "users/2/following", :user, {:response => :paginated}) do |h|
65 | h["meta"]["more"] = true
66 | h["data"][0]["pagination_id"] = "4621"
67 | end %>
68 |
69 | ## List users following a user
70 |
71 | Returns a list of User objects for users following the specified user. Please note that the pagination is not based on user or post ids.
72 |
73 | <%= general_params_note_for "user" %>
74 |
75 | <%= pagination_note %>
76 |
77 | <%= endpoint "GET", "users/[user_id]/followers", "Any" %>
78 |
79 | <%= url_params [
80 | ["user_id","The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
81 | ]%>
82 |
83 | #### Example
84 |
85 | <%= curl_example(:get, "users/2/followers", :user, {:response => :paginated}) do |h|
86 | h["meta"]["more"] = true
87 | h["data"][0]["pagination_id"] = "2889"
88 | end %>
89 |
90 | ## List user ids a User is following
91 |
92 | Returns an array of user ids the specified user is following.
93 |
94 | <%= endpoint "GET", "users/[user_id]/following/ids", "Any" %>
95 |
96 | <%= url_params [
97 | ["user_id","The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
98 | ]%>
99 |
100 | #### Example
101 |
102 | <%= curl_example(:get, "users/#{get_id(:user)}/following/ids", ["2", "3"]) %>
103 |
104 | ## List user ids following a user
105 |
106 | Returns an array of user ids for users following the specified user.
107 |
108 | <%= endpoint "GET", "users/[user_id]/followers/ids", "Any" %>
109 |
110 | <%= url_params [
111 | ["user_id","The user id. If the user id is me the current authenticated user will be used. You can also specify @username as a user_id."]
112 | ]%>
113 |
114 | #### Example
115 |
116 | <%= curl_example(:get, "users/#{get_id(:user)}/followers/ids", ["2", "3"]) %>
117 |
--------------------------------------------------------------------------------
/content/reference/resources/stream-marker/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Stream Marker"
3 | ---
4 |
5 | # Stream Marker
6 |
7 | * TOC
8 | {:toc}
9 |
10 | Stream markers allows a User's position in a stream of Posts to be synced between multiple App.net clients. Then when you go from the browser to your phone, your stream is right where you left off. The current stream marker will be included in the [response envelope](/reference/make-request/responses/#response-envelope) from any stream that returns Posts.
11 |
12 | ## Example Stream Marker
13 |
14 | If a Stream Marker hasn't yet been set, you will receive the following format:
15 |
16 | <%= json(:marker) %>
17 |
18 | A marker that has been set will look like this:
19 |
20 | <%= json(:full_marker) %>
21 |
22 | ## Stream Marker fields
23 |
24 |
25 |
26 |
Field
27 |
Type
28 |
Description
29 |
30 |
31 |
id
32 |
string
33 |
The Post id of the Post at the top of the stream when this Stream's position was last synced.
34 |
35 |
36 |
last_read_id
37 |
string
38 |
The largest `id` the App.net server has seen for this stream marker. This is useful when determining what posts a user has seen regardless of whether they've scrolled backward in time. This value always increases unless it's explicitly set backwards.
39 |
40 |
41 |
name
42 |
string
43 |
The name of the Stream this marker is for.
44 |
45 |
46 |
percentage
47 |
integer
48 |
An optional field that indicate what percentage this post has been scrolled in the stream. It defaults to 0. This allows for very precise stream syncing but since different clients render Posts with different heights it won't be consistent across different clients.
49 |
50 |
51 |
updated_at
52 |
string
53 |
The time this marker was last updated in ISO 8601 format.
54 |
55 |
56 |
version
57 |
string
58 |
A unique identifier updated every time this Stream Marker is updated.
59 |
60 |
61 |
62 | ## Update a Stream Marker
63 |
64 | Update the User's current place in a Stream. To update a Stream Marker, you can POST an object that matches the [Stream Marker schema](/reference/resources/stream-marker/) with an HTTP header of `Content-Type: application/json`. Only the `id`, `name`, and `percentage` fields will be used. `name` will come from the marker you received in the last GET request you made for the stream. You can update multiple stream markers at once by POSTing a list of stream markers instead of a single one.
65 |
66 | The purpose of a Stream Marker is _not_ to allow a user to scroll a stream on one device and see the scroll happen on another device in realtime. A stream marker should only be updated when a user has stopped scrolling (i.e. the stream's position hasn't changed in multiple seconds) or when the app is being closed. Please make sure your code understands our [rate limit headers](/reference/make-request/rate-limits/#response-headers) so if the rate limits for this endpoint change in the future your app handles this gracefully.
67 |
68 | The `last_read_id` is updated if the provided `id` is larger than the current value of `last_read_id`. If you would like to explicitly set the `last_read_id` to a smaller value, you can pass the query string parameter `reset_read_id=1` when updating a stream marker.
69 |
70 | <%= endpoint "POST", "posts/marker", "User" %>
71 |
72 | #### Example
73 |
74 | <% data = {
75 | "name" => "global",
76 | "id" => "2"
77 | } %>
78 |
79 | <%= curl_example(:post, "posts/marker", :full_marker) do |h|
80 | h["data"]["id"] = h["data"]["last_read_id"] = data["id"]
81 | h["data"]["name"] = data["name"]
82 | h["data"]["updated_at"] = "2012-11-12T20:04:58Z"
83 | h["data"]["version"] = "d95o2uzYI7q7tY7bHI4U1xBug7s"
84 | end %>
85 |
--------------------------------------------------------------------------------
/content/reference/resources/channel/subscriptions.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Channel Subscriptions"
3 | ---
4 |
5 | # Channel Subscription
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Get current user's subscribed channels
11 |
12 | Retrieve an "inbox" of the channels the user is currently subscribed to. This stream is ordered like an inbox with the stream containing the most recent post first.
13 |
14 | The `meta` response will contain unread counts for common channel types.
15 |
16 | <%= general_params_note_for "channel" %>
17 |
18 | <%= pagination_note %>
19 |
20 | <%= endpoint "GET", "channels", "User", "public_messages or messages"%>
21 |
22 | #### Example
23 |
24 | <%= curl_example(:get, "channels", :channel, {:response => :paginated}) do |h|
25 | h["data"][0]["pagination_id"] = "146"
26 | h["meta"]["more"] = true
27 | h["meta"]["unread_counts"] = {
28 | "net.app.core.pm" => 5,
29 | "net.app.core.broadcast" => 3
30 | }
31 | end %>
32 |
33 | ## Subscribe to a Channel
34 |
35 | Subscribe to a Channel. This adds it to your [Channel stream](#get-current-users-subscribed-channels). If a user has [muted this Channel](/reference/resources/channel/muting/#mute-a-channel), this call will automatically unmute the Channel.
36 |
37 | <%= general_params_note_for "channel" %>
38 |
39 | <%= endpoint "POST", "channels/[channel_id]/subscribe", "User", "public_messages or messages"%>
40 |
41 | <%= url_params [
42 | ["channel_id", "The id of the Channel to subscribe to."]
43 | ]%>
44 |
45 | #### Example
46 |
47 | <%= curl_example(:post, "channels/1/subscribe", :channel) do |h|
48 | h["data"]["you_subscribed"] = true
49 | end %>
50 |
51 | ## Unsubscribe from a Channel
52 |
53 | Unsubscribe from a Channel. This removes it from your [Channel stream](#get-current-users-subscribed-channels).
54 |
55 | <%= general_params_note_for "channel" %>
56 |
57 | <%= endpoint "DELETE", "channels/[channel_id]/subscribe", "User", "public_messages or messages"%>
58 |
59 | <%= url_params [
60 | ["channel_id", "The id of the Channel to unsubscribe from."]
61 | ]%>
62 |
63 | #### Example
64 |
65 | <%= curl_example(:delete, "channels/1/subscribe", :channel) do |h|
66 | h["data"]["counts"]["subscribers"] -= 1
67 | h["data"]["you_subscribed"] = false
68 | end %>
69 |
70 | ## Retrieve users subscribed to a Channel
71 |
72 | Retrieve the users who are subscribed to a Channel.
73 |
74 | <%= general_params_note_for "channel" %>
75 |
76 | <%= pagination_note %>
77 |
78 | <%= endpoint "GET", "channels/[channel_id]/subscribers", "Any", "public_messages or messages"%>
79 |
80 | <%= url_params [
81 | ["channel_id", "The id of the Channel to retrieve subscribers for."]
82 | ]%>
83 |
84 | #### Example
85 |
86 | <%= curl_example(:get, "channels/1/subscribers", :channel, {:response => :paginated}) do |h|
87 | h["meta"]["more"] = true
88 | h["data"][0]["pagination_id"] = "82"
89 | end %>
90 |
91 | ## Retrieve user ids subscribed to a Channel
92 |
93 | Retrieve all the user ids who are subscribed to a Channel.
94 |
95 | <%= endpoint "GET", "channels/[channel_id]/subscribers/ids", "Any", "public_messages or messages"%>
96 |
97 | <%= url_params [
98 | ["channel_id", "The id of the Channel to retrieve subscriber ids for."]
99 | ]%>
100 |
101 | #### Example
102 |
103 | <%= curl_example(:get, "channels/1/subscribers/ids", ["1"]) %>
104 |
105 | ## Retrieve user ids subscribed to multiple Channels
106 |
107 | For each requested Channel, retrieve the ids of all Users who are subscribed to that Channel. Up to 200 Channels may be requested at one time. Channels which do not exist or which the requesting user does not have authorization to view will not be returned.
108 |
109 | <%= endpoint "GET", "channels/subscribers/ids", "Any", "public_messages or messages"%>
110 |
111 | <%= query_params [
112 | ["ids", "A comma separated list of Channel ids to retrieve subscriber ids for."]
113 | ]%>
114 |
115 | #### Example
116 |
117 | Channels 3 and 5 are omitted as if they are not visible or do not exist
118 |
119 | <%= curl_example(:get, "channels/1/subscribers/ids?ids=1,2,3,5", {
120 | "1" => ["5", "10"],
121 | "2" => ["5", "20"]
122 | }) %>
123 |
--------------------------------------------------------------------------------
/content/reference/resources/message/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Message Lifecycle"
3 | ---
4 |
5 | # Message Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Create a Message
11 |
12 | Create a [Message](/reference/resources/message/) in the specified Channel.
13 |
14 | Send a JSON document that matches the [Message schema](/reference/resources/message/) with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `text`, `reply_to`, `annotations`, `entities`, and `machine_only`.
15 |
16 | If you would like to specify your own entities, please refer to the [user specified entites](/reference/meta/entities/#user-specified-entities) documentation, otherwise we will parse out links, hashtags, and mentions from the `text` field.
17 |
18 | If you want to test how your text will be processed you can use the [text processor](/reference/resources/text-processor).
19 |
20 | #### Creating Private Messages for use with net.app.core.pm Channels
21 |
22 | To create private group messages for use in `net.app.core.pm` channels, you can specify the special `channel_id` of `pm`. With this parameter, the server will look for an extra field in the provided message object called `destinations` which is a list of user ids to send this message to. If a private message channel already exists between this group of users, its `channel_id` will be reused. Otherwise, a new channel will be created and the users specified in the `destinations` list will be auto-subscribed (according to their [subscription preferences](https://account.app.net/settings/privacy/#messaging)) and able to write to that channel. Note that the `destinations` value may include user ids in the form of "@username" or integer id.
23 |
24 | <%= general_params_note_for "message" %>
25 |
26 | <%= endpoint "POST", "channels/[channel_id]/messages", "User" %>
27 |
28 | <%= url_params [
29 | ["channel_id", 'The id of the Channel in which to create the Message. Alternatively, you can specify pm to auto-create/reuse a net.app.core.pmprivate message channel.']
30 | ]%>
31 |
32 | #### Generic Channel Example
33 |
34 | <% data = {
35 | "text" => "Hello channel!",
36 | } %>
37 | <%= curl_example(:post, "channels/1/messages", :message, {:data => data}) %>
38 |
39 | #### PM Channel Example
40 |
41 | <% data = {
42 | "text" => "Hello channel!",
43 | "destinations" => ["@berg", 1]
44 | } %>
45 | <%= curl_example(:post, "channels/pm/messages", :message, {:data => data}) do |h|
46 | h["data"]["channel_id"] = "2"
47 | h["data"]["id"] = "105"
48 | h["data"]["thread_id"] = "105"
49 | end %>
50 |
51 | ## Delete a Message
52 |
53 | Delete a message. The current user must be the same user who created the Message. It returns the deleted Message on success.
54 |
55 | *You can always delete a message you created even if you are no longer able to view the rest of the Channel anymore.*
56 |
57 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
58 |
59 | <%= general_params_note_for "message" %>
60 |
61 | <%= endpoint "DELETE", "channels/[channel_id]/messages/[message_id]", "User", "public_messages or messages" %>
62 |
63 | <%= url_params [
64 | ["channel_id", "The id of the Channel this Message belongs to."],
65 | ["message_id", "The id of the Message to delete."]
66 | ]%>
67 |
68 | #### Example
69 |
70 | <%= curl_example(:delete, "channels/1/messages/1", :message) do |h|
71 | h["data"]["is_deleted"] = true
72 | h["data"].delete("text")
73 | h["data"].delete("html")
74 | h["data"]["entities"].each { |k, v| h["data"]["entities"][k] = []}
75 | end %>
76 |
77 |
78 | ## Retrieve the Messages in a Channel
79 |
80 | Retrieve a stream of the Messages in a channel.
81 |
82 | <%= general_params_note_for "message" %>
83 |
84 | <%= pagination_note %>
85 |
86 | <%= endpoint "GET", "channels/[channel_id]/messages", "User", "public_messages or messages" %>
87 |
88 | <%= url_params [
89 | ["channel_id", "The id of the Channel to retrieve Messages from."]
90 | ]%>
91 |
92 | #### Example
93 |
94 | <%= curl_example(:get, "channels/1/messages", :message, {:response => :paginated}) do |h|
95 | h["meta"]["marker"] = {"name" => "channel:1"}
96 | end %>
97 |
--------------------------------------------------------------------------------
/content/reference/resources/filter/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Filter Lifecycle"
3 | ---
4 |
5 | # Filter Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Create a Filter
11 |
12 | Create a [Filter](/reference/resources/filter/) for the current user.
13 |
14 | Send a JSON document that matches the [Filter schema](/reference/resources/filter/) with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `name`, `match_policy` and `clauses`.
15 |
16 | <%= endpoint "POST", "filters", "User" %>
17 |
18 | #### Data
19 |
20 | A JSON object representing the [Filter](/reference/resources/filter/) to create.
21 |
22 | #### Example
23 |
24 | <% data = {
25 | "clauses" => [
26 | {
27 | "field" => "/data/entities/hashtags/*/name",
28 | "object_type" => "post",
29 | "operator" => "matches",
30 | "value" => "rollout"
31 | }
32 | ],
33 | "id" => "1",
34 | "match_policy" => "include_any",
35 | "name" => "Posts about rollouts",
36 | }%>
37 | <%= curl_example(:post, "filters", :filter, {:data => data}) %>
38 |
39 | ## Retrieve a Filter
40 |
41 | Returns a specific [Filter](/reference/resources/filter/) object.
42 |
43 | <%= endpoint "GET", "filters/[filter_id]", "User" %>
44 |
45 | <%= url_params [
46 | ["filter_id", "The id of the Filter to retrieve."]
47 | ]%>
48 |
49 | #### Example
50 |
51 | <%= curl_example(:get, "filters/1", :filter) %>
52 |
53 | ## Get current user's Filters
54 |
55 | Return the [Filter](/reference/resources/filter/) for the current user.
56 |
57 | <%= endpoint "GET", "filters", "User" %>
58 |
59 | #### Example
60 |
61 | <%= curl_example(:get, "filters", :filter, {:response => :collection}) %>
62 |
63 | ## Update a Filter
64 |
65 | Updates a specific [Filter](/reference/resources/filter/) object. When a filter is updated, all the streams using the filter will start using the new filter criteria. You can update a filter by PUTing an object that matches the [Filter schema](/reference/resources/filter/) with an HTTP header of `Content-Type: application/json`. The entire filter will be replaced with new value but it's `id` will remain the same. Please refer to the documentation on [how to create a Filter](#create-a-filter) for more information.
66 |
67 | <%= endpoint "PUT", "filters/[filter_id]", "User" %>
68 |
69 | <%= url_params [
70 | ["filter_id", "The id of the Filter to update."]
71 | ]%>
72 |
73 | #### Example
74 |
75 | <% data = {
76 | "match_policy" => "include_any",
77 | "clauses" => [
78 | {
79 | "operator" => "matches",
80 | "field" => "/data/entities/hashtags/*/name",
81 | "object_type" => "post",
82 | "value" => "rollout"
83 | }, {
84 | "operator" => "matches",
85 | "field" => "/data/entities/hashtags/*/name",
86 | "object_type" => "post",
87 | "value" => "bug"
88 | }
89 | ],
90 | "name" => "Posts about rollouts or bugs"
91 | } %>
92 | <%= curl_example(:put, "filters/1", :filter, {:data => data}) do |h|
93 | h["data"]["clauses"] = data["clauses"]
94 | h["data"]["name"] = data["name"]
95 | end %>
96 |
97 | ## Delete a Filter
98 |
99 | Delete a [Filter](/reference/resources/filter/). The Filter must belong to the current User. It returns the deleted Filter on success.
100 |
101 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
102 |
103 | <%= endpoint "DELETE", "filters/[filter_id]", "User" %>
104 |
105 | <%= url_params [
106 | ["filter_id", "The id of the Filter to delete."]
107 | ]%>
108 |
109 | #### Example
110 |
111 | <%= curl_example(:delete, "filters/1", :filter) %>
112 |
113 | ## Delete all of the current user's Filters
114 |
115 | Delete all [Filters](/reference/resources/filter/) for the current user. It returns the deleted Filters on success.
116 |
117 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
118 |
119 | <%= endpoint "DELETE", "filters", "User" %>
120 |
121 | #### Example
122 |
123 | <%= curl_example(:delete, "filters", :filter, {:response => :collection}) %>
124 |
--------------------------------------------------------------------------------
/content/reference/resources/app-stream/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "App Stream Lifecycle"
3 | ---
4 |
5 | # App Stream Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Create a Stream
11 |
12 | Create a [Stream](/reference/resources/app-stream/) for the current token.
13 |
14 | Send a JSON document that matches the [stream schema](/reference/resources/app-stream/) with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `object_types`, `type`, `filter_id` and `key`. If you don't want to specify a filter, omit `filter_id`. If you don't want to specify a key, omit `key`.
15 |
16 | You can create up to 5 streams per App token.
17 |
18 | <%= endpoint "POST", "streams", "App" %>
19 |
20 | #### POST Data
21 |
22 | A JSON object representing the stream to create. See [the stream object](/reference/resources/app-stream/) for more information. Specify `filter_id` instead of `filter` if you want to filter this stream. (Omit the `id` and `endpoint` parameters).
23 |
24 | #### Example
25 |
26 | <% data = {
27 | "object_types" => ["post"],
28 | "type" => "long_poll",
29 | "filter_id" => "1",
30 | "key" => "rollout_stream"
31 | } %>
32 | <%= curl_example(:post, "streams", :app_stream, {:data => data, :token => ""})%>
33 |
34 |
35 | ## Retrieve a Stream
36 |
37 | Returns a specific [Stream](/reference/resources/app-stream/) object.
38 |
39 | <%= endpoint "GET", "streams/[stream_id]", "App" %>
40 |
41 | <%= url_params [
42 | ["stream_id", "The id of the Stream to retrieve."]
43 | ]%>
44 |
45 | #### Example
46 |
47 | <%= curl_example(:get, "streams/1", :app_stream, {:token => ""}) %>
48 |
49 | ## Get current token's Streams
50 |
51 | Return the [Streams](/reference/resources/app-stream/) for the current token.
52 |
53 | <%= endpoint "GET", "streams", "App" %>
54 |
55 | <%= query_params [
56 | ["key", "(Optional) Only retrieve the stream that matches the given key."]
57 | ]%>
58 |
59 | #### Example
60 |
61 | <%= curl_example(:get, "streams?key=rollout_stream", :app_stream, {:response => :collection, :token => ""}) %>
62 |
63 | ## Update a Stream
64 |
65 | Update a [Stream](/reference/resources/app-stream/). You can update a Stream by PUTing a JSON document that matches the [stream schema](/reference/resources/app-stream/) with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `object_types`, `type`, `filter_id` and `key`. If you don't want to specify a filter, omit `filter_id`. If you don't want to specify a key, omit `key`.
66 |
67 | <%= endpoint "PUT", "streams/[stream_id]", "App" %>
68 |
69 | <%= url_params [
70 | ["stream_id", "The id of the Stream to update."]
71 | ]%>
72 |
73 | #### Example
74 |
75 | <% data = {
76 | "object_types" => ["post","star"],
77 | "type" => "long_poll",
78 | "filter_id" => "1",
79 | "key" => "rollout_stream"
80 | } %>
81 | <%= curl_example(:put, "streams/1", :app_stream, {:data => data, :token => ""}) do |h|
82 | h["data"]["object_types"] = data["object_types"]
83 | end %>
84 |
85 | ## Delete a Stream
86 |
87 | Delete a [Stream](/reference/resources/app-stream/). The Stream must belong to the current User. It returns the deleted Stream on success.
88 |
89 | If you'd like your app stream to be automatically deleted when you disconnect from it, please add the [`auto_delete=1`](/reference/resources/user-stream/#limits) query string parameter when you connect to your app stream.
90 |
91 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
92 |
93 | <%= endpoint "DELETE", "streams/[stream_id]", "App" %>
94 |
95 | <%= url_params [
96 | ["stream_id", "The id of the Stream to delete."]
97 | ]%>
98 |
99 | #### Example
100 |
101 | <%= curl_example(:delete, "streams/1", :app_stream, {:token => ""}) %>
102 |
103 | ## Delete all of the current user's Streams
104 |
105 | Delete all [Streams](/reference/resources/app-stream/) for the current token. It returns the deleted Streams on success.
106 |
107 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
108 |
109 | <%= endpoint "DELETE", "streams", "App" %>
110 |
111 | #### Example
112 |
113 | <%= curl_example(:delete, "streams", :app_stream, {:response => :collection, :token => ""}) %>
114 |
--------------------------------------------------------------------------------
/content/docs/guides/messaging.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Messaging Overview"
3 | ---
4 |
5 | # App.net Messaging
6 |
7 | The App.net Messaging API allows a User to create public, private, semi-private messages between an arbitrary number of users. If you'd like to create public messages that your App.net followers see in their streams, you should [create a post](/reference/resources/post/lifecycle/#create-a-post) with the Stream API. If you need a more flexible messaging solution, the Messaging API is for you.
8 |
9 | Our messaging API is built around 2 central objects: [Channels](/reference/resources/channel/) and [Messages](/reference/resources/message/). If you're familiar with the App.net Stream API, here are some analogies:
10 |
11 | * Messages are like Posts
12 | * Channels are like streams of Posts
13 | * Stream markers work on Channels just like they work on streams of Posts
14 |
15 | When you create a Channel, you decide who can read and write to that channel. This flexibility lets you:
16 |
17 | * Create a private group chat between multiple App.net users
18 | * Create a moderated group that can be read by a set of users and written to by a different set of users
19 | * Create a chat room where App.net users can read and write messages while they're in the room and leave whenever they want
20 |
21 | If a user is authorized to read a Channel, they can also subscribe to a channel. This allows you to keep track of channels an messages at a more granular level.
22 |
23 | ## Authorization
24 |
25 | Access to Messages in a given Channel is determined by the [ACL fields](/reference/resources/channel/#acl-fields) on the Channel itself.
26 |
27 | Channels can be public or private. For the purpose of access tokens, a Channel is considered public if it is readable by unauthenticated users (the `public` flag) or any authenticated ADN user (the `any_user` flag).
28 |
29 | Application access to messages is governed by two scopes: `messages` and `public_messages`. The `messages` scope grants a superset of the permissions granted by the `public_messages` scope — it is unnecessary to request both scopes for a given application. The difference between the two is that only public Channels are visible to applications authorized with the `public_messages` scope.
30 |
31 | In addition, an App access token has read access to a Channel and its contents when:
32 |
33 | 1. the Channel is public, or
34 | 2. the Channel is private, and at least one user with read permission has authorized the application with the `messages` scope.
35 |
36 | ## Subscriptions
37 |
38 | Users indicate their interest in a given channel by subscribing to it. When a channel is created, no one is subscribed to it.
39 |
40 | [Private message channels](/reference/resources/channel/#private-message) (type `net.app.core.pm`) auto-subscribe all participants to the channel in accordance with each user's [subscription preferences](https://account.app.net/settings/privacy/#messaging).
41 |
42 | To get this same behavior for non-pm channels, you include the key `auto_subscribe: true` when you create or update the Channel. This will auto-subscribe all the users on the ACLs (according to their preferences).
43 |
44 | If a user has [muted a channel](/reference/resources/channel/muting/#mute-a-channel) they will never be auto-subscribed to it.
45 |
46 | ## Annotations
47 |
48 | Both Channel and Message objects allow for annotations; however, the details of each annotation implementation vary. Channel annotations act like User annotations — they are unique by type and mutable by the Channel's owner. Message annotations act like Post annotations — they are immutable.
49 |
50 | ## Markers
51 |
52 | The unread state of each Channel is tracked by a stream marker like those used for Posts. We suggest you do not advance a channel stream marker in reverse. When requested with a specific user token, each Channel exposes whether it contains a newer Message than the current marker position for the purpose of displaying an 'unread' indicator.
53 |
54 | ## Streaming
55 |
56 | Messages, channel updates and marker updates are pushed as objects over the streaming API. Channel permissions for the streaming API are related to the App access token as described above. Objects retrieved from the streaming API are not personalized to a given user.
57 |
58 | ## Types
59 |
60 | Much like annotation types, channel types are freeform strings; we suggest you use a reversed-domain format for any custom channel types. Core channel types are prefixed with `net.app.core` and may have additional validation imposed by the App.net API. Currently defined core channel types are:
61 |
62 | * [Private Message](/reference/resources/channel/#private-message): net.app.core.pm
63 | * [Broadcast Channel](/reference/resources/channel/#broadcast-channel): net.app.core.broadcast
64 |
--------------------------------------------------------------------------------
/content/docs/guides/create-an-app.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Create an App"
3 | ---
4 |
5 | # Getting Started With Development
6 |
7 | To start accessing parts of the API that require authentication you will need an **access token**. The easiest way to create an access token is to register an app in your [account dashboard](https://account.app.net/settings/).
8 |
9 | ## Creating an App
10 |
11 | 1. Start by visiting [account.app.net/settings/](https://account.app.net/settings/). Click on "[Your Apps](https://account.app.net/developer/apps/)" in the bottom left hand corner to go to Your Apps Dashboard.
12 |
13 | 
14 |
15 | 2. Click "[Create An App](https://account.app.net/developer/app/create/)."
16 |
17 | 
18 |
19 | 3. Fill in information about your app.
20 |
21 | All of the form details are required but you can always edit them later if you'd like to change anything. Give your app a unique name and provide a URL for users to find out more information. If it doesn't make sense for you to enter a website feel free to use your Alpha profile URL: `https://app.net/{YOUR USERNAME}`. This will let others know who is responsible for this app.
22 |
23 | The *Redirect URL* is used when your app [authenticates new users](/reference/authentication/). If you're not sure what to fill in, you can use `http://localhost:8000` (which we've already filled in for you).
24 |
25 | Once all the fields are filled in, click "Create."
26 |
27 | 
28 |
29 | 4. Your app is now created. From here you can copy your *Client ID* and *Client Secret* into your code and use them. You can also add additional *Redirect URLs* for other development or production environments. To generate an access token, follow the instructions in the next section of this page.
30 |
31 | 
32 |
33 | ## Generating an Access Token
34 |
35 | There are a few ways to get an access token, but the easiest way to get an access token for personal use or experimentation is to generate one from your app detail page.
36 |
37 | 1. Visit [account.app.net/developer/apps/](https://account.app.net/developer/apps/). Find the app you would like to generate an access token for and click on the name.
38 |
39 | 
40 |
41 | 2. Click "Generate a user token for yourself"
42 |
43 | 
44 |
45 | 3. Select the scopes for this token.
46 |
47 | To find out more about scopes your can [read the scope docs](/reference/authentication/#scopes). If you have previously generated a token, some of these boxes may already be checked.
48 |
49 | Once you have determined which scopes you will need select them in the form and then click "Generate."
50 |
51 | 
52 |
53 | 4. You now have a user access token for your app. You can copy that into your code and use it with a [client library](/docs/libraries/) or directly from curl.
54 |
55 |
56 | Remember: An access token is just like a password. It will allow applications to interact with the API on your behalf. So, keep it secret.
57 |
58 |
59 | 
60 |
61 | ## Launching your app
62 |
63 | Before you learn more about the API and start building your app, we want to make sure you know about some other opportunities for when you're ready to launch your app.
64 |
65 | ### Directory
66 |
67 | We want to make sure App.net users can find all the great apps that get created so we created the [App.net Directory](https://directory.app.net/). To include your app in the directory, you must [**register your app with us**](https://alpha.app.net/developer/apps/). For more information about how the directory, please see the [Directory Requirements](https://mml.desk.com/customer/portal/articles/779115-what-are-the-criteria-for-being-accepted-into-the-app-net-directory-).
68 |
69 |
70 | ### Developer Incentive Program
71 |
72 | To financially reward the development of great apps, [we announced the Developer Incentive Program](http://blog.app.net/2012/09/27/announcing-the-app-net-developer-incentive-program/). If you'd like to include your app you must [**register for the Developer Incentive Program**](https://alpha.app.net/developer/enrollment/).
73 |
74 | ## What's Next?
75 |
76 | Now that you have an access token you can use it to access authenticated parts of the API.
77 |
78 | You could:
79 |
80 | * [Send a broadcast](/docs/guides/send-a-broadcast/)
81 | * [Create a post](/docs/guides/create-a-post/)
82 |
83 | Or, you could build something completely new. We always love to see new apps.
84 |
--------------------------------------------------------------------------------
/content/docs/guides/using-annotations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Using Annotations"
3 | ---
4 |
5 | # Using Annotations
6 |
7 | * TOC
8 | {:toc}
9 |
10 | Annotations are metadata that can be attached to Users, Posts, Channels, Messages, or Files. This allows developers and users to add extra information to App.net objects outside of the fields App.net has already defined.
11 |
12 | ## What's so great about annotations?
13 |
14 | Annotations give developers a tremendous degree of freedom to expand upon the core functionality of App.net. They provide a way for developers to add arbitrary data to App.net objects, enabling richer content and new services.
15 |
16 | Let's say I'm at a restaurant eating a great dinner, but instead of just telling my followers about this restaurant I want them to be able to see a map of where it is. My Post could include geographic information about the address for the restaurant in an annotation and then clients that support this geographic annotation could show the restaurant on a map (in addition to showing my post). If the restaurant is on [OpenTable](http://www.opentable.com), I could include an annotation indicating that and my followers could see the menu and make a reservation in their own App.net client.
17 |
18 | ## Anatomy of an annotation
19 |
20 | Annotations are a list of objects that have a `type` and a `value`.
21 |
22 | <%= json_output([
23 | {
24 | "type" => "com.example.awesome",
25 | "value" => {
26 | "annotations work" => "beautifully"
27 | }
28 | }
29 | ]) %>
30 |
31 | The `type` field identifies essentially a schema for the `value` of the annotation. Please see the [annotations reference](/reference/meta/annotations/#documenting-annotations) for more information about different kinds of annotations.
32 |
33 | ## Example: Attach an image to a post
34 |
35 | When you see an image included in an App.net post, you see the results of annotations at work. We'll be using the [`net.app.core.oembed`](https://github.com/appdotnet/object-metadata/blob/master/annotations/net.app.core.oembed.md) annotation to embed a photo in an App.net post.
36 |
37 | <% data = {
38 | "text" => "Hello App.net from curl, with a photo!",
39 | "annotations" => [
40 | {
41 | "type" => "net.app.core.oembed",
42 | "value" => {
43 | "type" => "photo",
44 | "version" => "1.0",
45 | "width" => 870,
46 | "height" => 106,
47 | "url" => "https://files.app.net/2jxk2CoP4",
48 | "thumbnail_width" => 200,
49 | "thumbnail_height" => 24,
50 | "thumbnail_url" => "https://files.app.net/2jxk12R7F",
51 | "embeddable_url" => "https://app.net"
52 | }
53 | }
54 | ]
55 | } %>
56 | <%= curl_example(:post, "posts?include_annotations=1", :none, {:data => data}) %>
57 |
58 | Most clients expect `thumbnail_url`, `thumbnail_width`, and `thumbnail_height` to render a preview inline with the post.
59 |
60 | ## Example: Attach an App.net file to a post as an image
61 |
62 | Most apps that include images don't generate a raw oembed annotation to an image hosted somewhere else, they use the [App.net File storage](/reference/resources/files/). To do this, first you have to upload a file to App.net and then you have to create the post with an annotation as we did above.
63 |
64 | ### Upload a file
65 |
66 | <%= curl_example(:post, "files", :none, {
67 | :files => {
68 | "type" => "testing.image",
69 | "content" => "@filename.png;type=image/png",
70 | }
71 | }) %>
72 |
73 |
74 | This will return a JSON blob similar with the following fields we care about:
75 |
76 | <%= json_output({
77 | "data" => {
78 | "file_token" => "1234567NQD4isqELTZlIiEd9fp24e5wC1NACSYFI_Svc7-hkvCKWOTsOPQLrrMiVu-9x2L400MbKlG4T8-WA97HokUdApqXwtQjJt9wOJ12ZZX_hZSFmj_O0xFlvJt8rwqaTAOvK7qECaj1LS131baLjJojErPB5TwZiQQJko0BU",
79 | "id" => "123",
80 | },
81 | }) %>
82 |
83 | ### Attach the file to a post
84 |
85 | Once we've uploaded the file, we can attach it to a post and let App.net generate the correct oembed annotation:
86 |
87 | <% data = {
88 | "text" => "Hello App.net from curl, with an App.net hosted photo!",
89 | "annotations" => [{
90 | "type" => "net.app.core.oembed",
91 | "value" => {
92 | "+net.app.core.file" => {
93 | "file_id" => "",
94 | "file_token" => "",
95 | "format" => "oembed"
96 | }
97 | }
98 | }]
99 | } %>
100 | <%= curl_example(:post, "posts?include_annotations=1", :none, {:data => data}) %>
101 |
102 | Since annotations can contain up to [8192 bytes of data](/reference/meta/annotations/#limit), they are not returned by default. We have to explicitly request that App.net return annotations by passing the `include_annotations=1` query string parameter.
103 |
--------------------------------------------------------------------------------
/content/reference/other/feeds.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Feeds"
3 | ---
4 |
5 | # Feeds
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Basic Use
11 |
12 | Feeds describe our system for simple syndication of public posts on App.net. We currently support RSS as a syndication format. This means you should be able to use them anywhere you currently use RSS feeds.
13 |
14 | There are 2 different kinds of feeds, but they all follow the same pattern:
15 |
16 | * Users Post feed: A feed for a single User's public posts on App.net. This is a feed version of the [Retrieve Posts created by a User](/reference/resources/post/streams/#retrieve-posts-created-by-a-user) endpoint.
17 | * Hashtag feed: A feed containing all public Posts that are tagged with a specific hashtag. This is a feed version of the [Retrieve tagged Posts](/reference/resources/post/streams/#retrieve-tagged-posts) endpoint.
18 |
19 | We intend to support more feed formats and richer support for filters in the near future.
20 |
21 | While the URLs are similar to other API URLs feeds, they are under a different root.
22 |
23 | ## Filters
24 |
25 | Feeds do not currently support filters or general parameters like the JSON API.
26 |
27 | ## Response Format
28 |
29 | All responses are returned as RSS. We are following the spec for RSS 2.0 as described in the [RSS 2.0 specification](http://cyber.law.harvard.edu/rss/rss.html).
30 |
31 | ## Retrieve a feed for a User
32 |
33 | Retrieve a feed for the User [@voidfiles](http://alpha.app.net/voidfiles). This endpoint is similar to the [Retrieve Posts created by a User](/reference/resources/post/streams/#retrieve-posts-created-by-a-user) endpoint.
34 |
35 | ### URL
36 | > https://alpha-api.app.net/feed/rss/users/@username/posts
37 |
38 | ### Example
39 |
40 | <% response = %q{
41 |
42 |
43 | Posts from voidfiles on App.net
44 | https://alpha.app.net/voidfiles
45 | Hi, I work at App.net
46 |
47 |
48 | Posts from voidfiles on App.net
49 | https://alpha.app.net/voidfiles
50 | https://dqdwyydysypcm.cloudfront.net/image/4/Go50UQd5N9mi_APkpQt9JAp4ZsDfMlOTnoB4P-0N5rmpFGtnro2b52yUcUr_bPbxKlxx_4EHHiujdE-RRpSB6oZd0bHGy4xKlwInNBClbebDS7DoyyPHtIK9LY5x-kQSdnPKyKhtogJxD04SGOQMLPkCasZM42nLVgZIIhcbmbBrzxNJaoRoCNOrzS1ib9fQcAwPEg
51 |
52 |
53 | voidfiles: #hashtag test
54 |
55 | #hashtag test
56 |
57 | Fri, 31 Aug 2012 17:15:31 +0000
58 | https://alpha.app.net/voidfiles/post/1387
59 | https://alpha.app.net/voidfiles/post/1387
60 | hashtag
61 |
62 |
63 | } %>
64 |
65 | <%= curl_example(:get, "users/@voidfiles/posts", response, {
66 | :token => nil,
67 | :response => :raw,
68 | :response_syntax => "xml",
69 | :path_prefix => "/feed/rss/",
70 | }) %>
71 |
72 | ## Retrieve a feed for a hashtag
73 |
74 | Retrieve a feed for the specified hashtag. This endpoint is similar to the [Retrieve tagged Posts](/reference/resources/post/streams/#retrieve-tagged-posts) endpoint.
75 |
76 | ### URL
77 | > https://alpha-api.app.net/feed/rss/posts/tag/hashtag
78 |
79 | ### Example
80 |
81 | <% response = %q{
82 |
83 |
84 | #hashtag - App.net
85 | https://alpha.app.net/hashtags/hashtag
86 | Posts about #hashtag
87 |
88 |
89 | voidfiles: #hashtag test
90 |
91 | #hashtag test
92 |
93 | Fri, 31 Aug 2012 17:15:31 +0000
94 | https://alpha.app.net/voidfiles/post/1387
95 | https://alpha.app.net/voidfiles/post/1387
96 | hashtag
97 |
98 |
99 | } %>
100 |
101 | <%= curl_example(:get, "posts/tag/hashtag", response, {
102 | :token => nil,
103 | :response => :raw,
104 | :response_syntax => "xml",
105 | :path_prefix => "/feed/rss/",
106 | }) %>
107 |
--------------------------------------------------------------------------------
/content/reference/resources/message/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Message Search"
3 | ---
4 |
5 | # Search
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Search for Messages
11 |
12 | Returns [Message](/reference/resources/message/) objects which match a given search query. This endpoint responds to a list of channel IDs which can either given specifically or performed on all PM or Broadcast channels that the user is subscribed to. Searches can either be ordered by `id` or `score`. Searches ordered by `id` require at least one query or filter to be specified; searches ordered by `score` require at least one query and zero or more filters to be specified. All parameters should be passed in the query string.
13 |
14 | All queries and filters are combined with an AND operation. Query parameters (not filter parameters) can use "quoted strings" for phrases, search syntax like +foo -bar and foo OR baz for boolean queries. Separate lists of terms by spaces.
15 |
16 | <%= general_params_note_for "message" %>
17 |
18 | <%= endpoint "GET", "channels/messages/search", "Any" %>
19 |
20 | <%= query_params_typed 'General Parameters', [
21 |
22 | ["index", :optional, "string", "Type of index to use. The default (and currently, the only) index is complete, which searches all messages. We may add additional index types later (e.g., an index only of recent messages, for speed.)"],
23 |
24 | ["order", :optional, "string", "One of: id (default), score. Searches of ordering id are returned in roughly the same order as other streams. Searches of ordering score are returned by a relevance score."],
25 |
26 | ]%>
27 |
28 | <%= query_params_typed 'Search Query Parameters', [
29 |
30 | ["query", :optional, "string", "Automatically attempts to extract hashtags and mentions while searching text. If you do not want this behavior, you can use more specific parameters below."],
31 | ["text", :optional, "string", "Include messages containing certain text."],
32 | ["channel_ids", :required, "string", "Specifies the list of channels to search through. This must either be a list of IDs or one of `pm`, `broadcast`. Channel ACLs will be respected (read permission must be granted to the user)."],
33 |
34 |
35 | ]%>
36 |
37 | <%= query_params_typed 'Filter Parameters', [
38 | ["hashtags", :optional, "string", "Only include messages tagged with certain hashtags. Do not include #"],
39 | ["links", :optional, "string", "Only include messages linking to certain URLs"],
40 | ["link_domains", :optional, "string", "Only include messages linking to certain domains. Do not include \"www.\""],
41 | ["mentions", :optional, "string", "Only include messages mentioning certain users, by username. Do not include @"],
42 | ["leading_mentions", :optional, "string", "Only include messages directed at users, by username. Do not include @"],
43 | ["annotation_types", :optional, "string", "Only include messages with a specific annotation type, e.g., net.app.core.fallback_url"],
44 | ["attachment_types", :optional, "string", "Only include messages with a specific file type attached via the net.app.core.file_list annotation"],
45 | ["place_id", :optional, "string", "Only include messages which are check-ins at a specific place, via the net.app.core.checkin annotation"],
46 |
47 | ["is_reply", :optional, "int (0 or 1)", "Only include replies"],
48 | ["is_directed", :optional, "int (0 or 1)", "Only include messages with leading mentions, i.e., messages which were directed at other users"],
49 | ["has_location", :optional, "int (0 or 1)", "Only include messages containing geo coordinates, i.e., tagged with the net.app.core.geolocation annotation"],
50 | ["has_checkin", :optional, "int (0 or 1)", "Only include messages containing place IDs, i.e., tagged with the net.app.core.checkin annotation"],
51 | ["has_attachment", :optional, "int (0 or 1)", "Only include messages with file attachments"],
52 | ["has_oembed_photo", :optional, "int (0 or 1)", "Only include messages with photo oembed annotations"],
53 | ["has_oembed_video", :optional, "int (0 or 1)", "Only include messages with video (not html5video) oembed annotations"],
54 | ["has_oembed_html5video", :optional, "int (0 or 1)", "Only include messages with html5video oembed annotations"],
55 | ["has_oembed_rich", :optional, "int (0 or 1)", "Only include messages with rich oembed annotations"],
56 |
57 | ["language", :optional, "string", "Only include messages with a certain language tagged with the net.app.core.language annotation."],
58 | ["client_id", :optional, "string", "Only include messages created by a certain app. Use the alphanumeric client_id"],
59 | ["creator_id", :optional, "string", "Only include messages created by a specific user. Use the user ID, not the username"],
60 | ["reply_to", :optional, "string", "Only include immediate replies to a given message ID"],
61 | ["thread_id", :optional, "string", "Only include messages on a specific thread"],
62 |
63 | ]%>
64 |
65 | #### Example
66 |
67 | <%= curl_example(:get, "channels/messages/search?query=hello&channel_ids=1&count=1", :message, {:response => :paginated}) do |h|
68 | h["meta"]["count"] = 1
69 | end %>
70 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/post.md:
--------------------------------------------------------------------------------
1 |
121 |
--------------------------------------------------------------------------------
/content/reference/resources/post/search.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Post Search"
3 | ---
4 |
5 | # Search
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Search for Posts
11 |
12 | Returns [Post](/reference/resources/post/) objects which match a given search query. Searches ordered by `id` require at least one query or filter to be specified; searches ordered by `score` require at least one query and zero or more filters to be specified. Searches require an ordering and at least one search query to be specified, and allow for zero or more filters to be added. All parameters should be passed in the query string.
13 |
14 | All queries and filters are combined with an AND operation. Query parameters (not filter parameters) can use "quoted strings" for phrases, search syntax like +foo -bar and foo OR baz for boolean queries. Machine-only posts are not included in the search index. Separate lists of terms by spaces.
15 |
16 | <%= general_params_note_for "post" %>
17 |
18 | <%= endpoint "GET", "posts/search", "Any" %>
19 |
20 | <%= query_params_typed 'General Parameters', [
21 |
22 | ["index", :optional, "string", "Type of index to use. The default (and currently, the only) index is complete, which searches all posts. We may add additional index types later (e.g., an index only of recent posts, for speed.)"],
23 |
24 | ["order", :optional, "string", "One of: id (default), score. Searches of ordering id are returned in roughly the same order as other streams. Searches of ordering score are returned by a relevance score."],
25 |
26 | ]%>
27 |
28 | <%= query_params_typed 'Search Query Parameters', [
29 |
30 | ["query", :optional, "string", "Automatically attempts to extract hashtags and mentions while searching text. If you do not want this behavior, you can use more specific parameters below."],
31 | ["text", :optional, "string", "Include posts containing certain text."],
32 |
33 |
34 | ]%>
35 |
36 | <%= query_params_typed 'Filter Parameters', [
37 | ["hashtags", :optional, "string", "Only include posts tagged with certain hashtags. Do not include #"],
38 | ["links", :optional, "string", "Only include posts linking to certain URLs"],
39 | ["link_domains", :optional, "string", "Only include posts linking to certain domains. Do not include \"www.\""],
40 | ["mentions", :optional, "string", "Only include posts mentioning certain users, by username. Do not include @"],
41 | ["leading_mentions", :optional, "string", "Only include posts directed at users, by username. Do not include @"],
42 | ["annotation_types", :optional, "string", "Only include posts with a specific annotation type, e.g., net.app.core.fallback_url"],
43 | ["attachment_types", :optional, "string", "Only include posts with a specific file type attached via the net.app.core.file_list annotation"],
44 | ["crosspost_url", :optional, "string", "Only include posts which are crossposts of a specific URL, via the net.app.core.crosspost annotation"],
45 | ["crosspost_domain", :optional, "string", "Similar to crosspost_url, but only match on the host portion of the URL. Do not include \"www.\""],
46 | ["place_id", :optional, "string", "Only include posts which are check-ins at a specific place, via the net.app.core.checkin annotation"],
47 |
48 | ["is_reply", :optional, "int (0 or 1)", "Only include replies"],
49 | ["is_directed", :optional, "int (0 or 1)", "Only include posts with leading mentions, i.e., posts which were directed at other users"],
50 | ["has_location", :optional, "int (0 or 1)", "Only include posts containing geo coordinates, i.e., tagged with the net.app.core.geolocation annotation"],
51 | ["has_checkin", :optional, "int (0 or 1)", "Only include posts containing place IDs, i.e., tagged with the net.app.core.checkin annotation"],
52 | ["is_crosspost", :optional, "int (0 or 1)", "Only include posts which are crossposts, i.e., tagged with the net.app.core.crosspost annotation"],
53 | ["has_attachment", :optional, "int (0 or 1)", "Only include posts with file attachments"],
54 | ["has_oembed_photo", :optional, "int (0 or 1)", "Only include posts with photo oembed annotations"],
55 | ["has_oembed_video", :optional, "int (0 or 1)", "Only include posts with video (not html5video) oembed annotations"],
56 | ["has_oembed_html5video", :optional, "int (0 or 1)", "Only include posts with html5video oembed annotations"],
57 | ["has_oembed_rich", :optional, "int (0 or 1)", "Only include posts with rich oembed annotations"],
58 |
59 | ["language", :optional, "string", "Only include posts with a certain language tagged with the net.app.core.language annotation."],
60 | ["client_id", :optional, "string", "Only include posts created by a certain app. Use the alphanumeric client_id"],
61 | ["creator_id", :optional, "string", "Only include posts created by a specific user. Use the user ID, not the username"],
62 | ["reply_to", :optional, "string", "Only include immediate replies to a given post ID"],
63 | ["thread_id", :optional, "string", "Only include posts on a specific thread"],
64 |
65 | ]%>
66 |
67 | #### Example
68 |
69 | <%= curl_example(:get, "posts/search?hashtags=adnhack&count=-1", :post, {:response => :paginated}) do |h|
70 | h["meta"]["count"] = 1
71 | h["data"][0]["pagination_id"] = "10000"
72 | end %>
73 |
--------------------------------------------------------------------------------
/content/reference/resources/file/lifecycle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "File Lifecycle"
3 | ---
4 |
5 | # File Lifecycle
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Create a File
11 |
12 | Create a new [File](/reference/resources/file/).
13 |
14 | An App.net File object can be created without setting the file content. This is called an "incomplete" file object. To create an incomplete file object, POST a JSON document that matches the [File schema](/reference/resources/file/) with an HTTP header of `Content-Type: application/json`. Currently, the only keys we use from your JSON will be `kind`, `type`, `name`, `public` and `annotations`. You can also send those keys as standard form data instead of as JSON. Once you have an incomplete file object, you can [set the file content](/reference/resources/file/content/#set-file-content) in a later request.
15 |
16 | You can also create a complete File object with one request by including the file content with the File metadata. To create a complete file object, send a POST with an HTTP header of `Content-Type: multipart/form-data`. Our API expects one part of the request body to contain a `Content-Disposition` header with a value for `filename` and `name="content"`. The data from this part will be used as the file's content. If you wish to send your data as Base64 encoded instead of as a byte stream you must include a `Content-Transfer-Encoding: base64` header. If there is a part with `name="metadata"` and `Content-Type: application/json` then we will parse that JSON as the file's metadata. Otherwise, we will construct the metadata from the `form-data` sent in the request body. If you send extra parts with a value for `filename`, the `name`
17 |
18 | When creating a complete file, this endpoint could return a `507 Insufficient Storage` error if the user doesn't have enough space for this file. For more information, see [file storage limits](/reference/resources/file/#limits).
19 |
20 | <%= general_params_note_for "file" %>
21 |
22 | <%= endpoint "POST", "files", "User" %>
23 |
24 | <%= file_token_reminder %>
25 |
26 | #### Example
27 |
28 | ##### JSON Metadata 2
29 |
30 | The most comprehensive way to to specify a file's attributes are to upload json data that fits the File schema with the file itself.
31 |
32 | <%= curl_example(:post, "files", :none, {
33 | :files => {
34 | "metadata" => "@-;type=application/json",
35 | "content" => "@filename.jpg",
36 | },
37 | :stdin => JSON.pretty_generate({
38 | "type" => "com.example.test",
39 | "annotations" => [
40 | {
41 | "type" => "com.example.annotation",
42 | "value" => {
43 | "foo" => "bar"
44 | }
45 | }
46 | ]
47 | })
48 | }) %>
49 |
50 | ##### Form-data metadata
51 |
52 | The metadata can also be submitted as normal post data. If you want to create annotations on the file, you must use the JSON metadata format to do so.
53 |
54 | Here is some [sample File upload code written in Python](https://gist.github.com/4659409). You can also use the following curl command to upload a file:
55 |
56 | <%= curl_example(:post, "files", :none, {
57 | :files => {
58 | "type" => "com.example.test",
59 | "content" => "@filename.jpg",
60 | },
61 | }) %>
62 |
63 | ##### Custom derived files
64 |
65 | If you'd like to upload [custom derived files](/reference/resources/file/#derived-files) at the same time as the original file, you can include the derived files as extra parts:
66 |
67 | <%= curl_example(:post, "files", :file, {
68 | :files => {
69 | "type" => "com.example.test",
70 | "content" => "@filename.jpg",
71 | "derived_key1" => "@derived_file1.png;type=image/png",
72 | "derived_key2" => "@derived_file2.png;type=image/png",
73 | }
74 | }) %>
75 |
76 | ## Update a File
77 |
78 | Updates a specific [File](/reference/resources/file/) object. You can update a file by PUTing an object that matches the [File schema](/reference/resources/file/) with an HTTP header of `Content-Type: application/json`. The only keys that can be updated are `annotations`, `name` and `public`. Only the File owner can update a File.
79 |
80 | This endpoint currently works identically for the `PUT` and `PATCH` HTTP methods.
81 |
82 | <%= general_params_note_for "file" %>
83 |
84 | <%= endpoint "PUT", "files/[file_id]", "User"%>
85 |
86 | <%= file_token_reminder %>
87 |
88 | <%= url_params [
89 | ["file_id", "The id of the File to update."]
90 | ]%>
91 |
92 | #### Example
93 |
94 | <% data = {"name" => "update_filename.jpg"}%>
95 | <%= curl_example(:put, "files/1", :file, {:data => data}) do |h|
96 | h["data"]["name"] = data["name"]
97 | end %>
98 |
99 | ## Delete a File
100 |
101 | Delete a file. The current user must be the same user who created the File. It returns the deleted File on success. *Since a File could be referenced by multiple resources we recommend that you don't automatically delete files when you delete Posts. Deleting a file should be a more explicit action taken by the user.*
102 |
103 | *Remember, access tokens can not be passed in a HTTP body for `DELETE` requests. Please refer to the [authentication documentation](/reference/authentication/#making-authenticated-api-requests).*
104 |
105 | <%= general_params_note_for "file" %>
106 |
107 | <%= endpoint "DELETE", "files/[file_id]", "User" %>
108 |
109 | <%= file_token_reminder %>
110 |
111 | <%= url_params [
112 | ["file_id", "The id of the File to delete."]
113 | ]%>
114 |
115 | #### Example
116 |
117 | <%= curl_example(:delete, "files/1", :file) %>
118 |
--------------------------------------------------------------------------------
/content/reference/authentication/flows/password.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Password Flow"
3 | ---
4 |
5 | # Password Flow
6 |
7 | * TOC
8 | {:toc}
9 |
10 | This flow is useful for obtaining an access token authorized for specific scopes when pushing the user into a browser-based flow is impractical for technical or user-experience reasons.
11 |
12 | This is referred to as the Resource Owner Password Credential flow in the OAuth 2.0 spec. However, in order to protect the integrity of `client_secret`s, we require the use of a separate token to be included with flows.
13 |
14 | ## Obtaining approval to use the password flow
15 |
16 | **Your application must be specifically approved to use this flow.** To obtain authorization, go to your [App.net developer dashboard](https://account.app.net/developer/apps/), select your app, and click **Request approval for password flow**. You will need to provide an explanation of your situation and then click the **Submit Request** button to complete your request for authorization. When your request has been approved you will receive an email with your password grant secret. The password grant secret token will also be available on your account page.
17 |
18 | ## Rules
19 |
20 | **Security of user accounts is the most important thing.** When in doubt, err on the side of securing user password information, rather than optimizing for user experience.
21 |
22 | > Some of these rules might limit what you can do with your app. Please do not attempt to circumvent them, or we will disable your application token. That may sound harsh, but it is of utmost importance that we protect the integrity of the service and the security of user accounts.
23 |
24 | > These flows should only be used in cases where browser-based authentication is impractical. For one-off applications, shell scripts, etc., please generate an access token for your app via [My Apps](https://account.app.net/developer/apps/).
25 |
26 | 1. **NEVER** store user password information, no matter how securely. Users should be able to disable access to your application at any time by revoking authorization. Access tokens are designed not to expire unless users take explicit action, so there is no need to build in a mechanism to reauthenticate that would require storing passwords.
27 | 1. **NEVER** send user password information over the network, except to the prescribed App.net OAuth endpoint.
28 | 1. **NEVER** log user password information, even debug logging to your app or device's console. It is too easy to accidentally leak password information this way.
29 | 1. Users **MUST** have a way to see which scopes are being requested by an application. This can be behind a "more info" button, but must at least be exposed on the login screen, before users are required to enter their password information to continue.
30 | 1. If an error is returned from the OAuth endpoint, it **MUST** be displayed to users verbatim.
31 | 1. If these rules are updated, application developers must make reasonable attempts to comply with new regulations wherever possible.
32 |
33 | ## Procedure
34 |
35 | > By default **users will receive an email each time they authorize an application with this flow** listing the name of the application, the scopes requested and the time that authorization was performed.
36 |
37 | Once you have been approved, using the password flow is pretty straightforward:
38 |
39 | 1. From your client, make a request to the token endpoint:
40 |
41 | POST https://account.app.net/oauth/access_token
42 |
43 | with URL-encoded POST body:
44 |
45 | client_id=[your client ID]
46 | &password_grant_secret=[your password grant secret, not your client secret]
47 | &grant_type=password
48 | &username=[user's email or username]
49 | &password=[user's password]
50 | &scope=[scopes separated by spaces]
51 |
52 | Example:
53 |
54 | <%= curl_example(:post, "access_token", :none, {
55 | :subdomain => "account",
56 | :path_prefix => "/oauth/",
57 | :pretty_json => false,
58 | :token => nil,
59 | :content_type => nil,
60 | :data => {
61 | "grant_type" => "password",
62 | "client_id" => "[your client_id]",
63 | "password_grant_secret" => "[your password grant secret that was emailed to you]",
64 | "username" => "[user's email address or username]",
65 | "password" => "[user's password]",
66 | "scope" => "[scopes separated by spaces]",
67 | }
68 | }) %>
69 |
70 | > The use of `password_grant_secret` diverges from the OAuth 2.0 specification. `password_grant_secret` is a special token that we'll send you when your use of the password flow is approved.
71 |
72 | > **You can require app-specific passwords** by providing a `require_app_specific_password=1` URL parameter. **[Two-Factor Auth users](http://blog.app.net/2013/03/13/added-security-for-your-app-net-account/) must use app-specific passwords** regardless of this parameter. We strongly encourage the use of app-specific passwords by all users as they significantly increase account security.
73 |
74 | 1. If the authorization was successful, App.net will respond with a JSON-encoded token:
75 |
76 | {"access_token": "[user access token]", "token": {...Token object...}}
77 |
78 | You can use this access_token to make authenticated calls to the App.net API on behalf of a user.
79 |
80 | 1. If authentication failed or there was another error, App.net will respond with an error:
81 |
82 | {"error": "Authentication failed"}
83 |
84 | If the `error_text` key is present in this dictionary, you **MUST** show a modal dialog or equivalent containing this text. If possible, you should include value of the `error_title` key as a title in your dialog.
85 |
--------------------------------------------------------------------------------
/content/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Home"
3 | ---
4 |
5 | # App.net API Documentation
6 |
7 | App.net is a developer-friendly social infrastructure platform. Our API is the primary interface by which developers interact with the platform. The documentation is broken into two parts: these guides and our [full API reference](/reference/).
8 |
9 | ## Quick Start
10 |
11 | The App.net API is powerful and flexible -- if you're new to the API, we suggest you start with these guides.
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Quick Start: Broadcast
22 |
23 |
Send a broadcast with the App.net API.
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Quick Start: Authentication
34 |
35 |
Learn how to make authenticated requests to the API.
36 |
37 |
38 |
39 |
40 |
41 |
42 | ## Notable API features
43 |
44 | ### Identity & Authentication
45 |
46 | Use App.net's identity layer to authenticate users and populate user profiles. For more information, see the [Authentication reference](/reference/authentication/) and [User reference](/reference/resources/user/).
47 |
48 | ### Social Graph
49 |
50 | App.net has a asymmetrical (follower-following) social graph which can be used to solve the "cold start" problem when a user signs into your app. The [Following reference](/reference/resources/user/following/) has more details.
51 |
52 | ### Messaging
53 |
54 | Channels are like chat rooms. They're a time ordered series of messages that can be public, private, or restricted to a group of App.net users. The messages inside of channels can take advantage of App.net files, places, and anything else the API provides. [Chat rooms](https://directory.app.net/app/145/patter/), [Broadcasts](http://blog.app.net/2013/11/21/announcing-app-net-broadcast/), and private messages are all built on top of [App.net Messaging](/docs/guides/messaging/).
55 |
56 | ### Places
57 |
58 | App.net has a location database that can be integrated with your app. This allows you to add location to Posts or Message to enable location aware apps. See the [Places reference](/docs/references/resources/places/) for more information.
59 |
60 | ### Annotations
61 |
62 | Annotations are machine readable metadata that can be attached to most App.net objects (posts, messages, users, and more). They power [checkins](https://alpha.app.net/browse/checkins/), [photos](https://alpha.app.net/browse/photos/) and other rich posts on App.net. See the [Annotations introduction](/docs/references/resources/meta/annotations/) to get started.
63 |
64 | ### Files
65 |
66 | App.net gives each user space to store and share files. These files can be shared publicly, attached to posts, or sent as a private message to a friend. All App.net apps share the same file storage space so if a new photo or video app comes along, you can check it out and not have to worry about migrating all your old data. See the [Files reference](/docs/references/resources/files/) for more information.
67 |
68 |
69 | ## Tracking news and announcements
70 |
71 | To see the latest updates to the API, follow [@adnapi](http://alpha.app.net/adnapi). You may also want to subscribe to the [App.net blog](https://broadcast.app.net/26283/appnet-blog/) for general news and the [App.net API Updates](https://broadcast.app.net/24368/appnet-api-updates/) Broadcast channel for developer related news.
72 |
73 | ## Getting help and providing feedback
74 |
75 | There are numerous ways for developers to get help utilizing the platform and to provide feedback.
76 |
77 | * Developers (including App.net staff) are often chatting in the [Developer Channel](http://patter-app.net/room.html?channel=1383).
78 | * For developer inquiries about the API, our Terms of Service, letting us know about something you're working on, etc., email [developers@app.net](mailto:developers@app.net).
79 | * For general inquiries about account/service related issues, email [support@app.net](mailto:support@app.net).
80 | * In addition to the above, you can report bugs and provide feedback on the API using the [issue tracker](https://github.com/appdotnet/api-spec/issues).
81 | * This documentation is open source. If you find an error or something that's unclear, let us know with a pull request or issue on the [Github repo for the documentation](https://github.com/appdotnet/api-spec/).
82 |
83 | ## Your hosts
84 |
85 | * [Bryan Berg](http://ber.gd) ([@berg](https://alpha.app.net/berg), [bryan@app.net](mailto:bryan@app.net))
86 | * Mark Thurman ([@mthurman](https://alpha.app.net/mthurman), [mthurman@app.net](mailto:mthurman@app.net))
87 | * [Alex Kessinger](http://alexkessinger.net) ([@voidfiles](https://alpha.app.net/voidfiles), [alex@app.net](mailto:alex@app.net))
88 | * Brian Armstrong ([@barmstrong](https://alpha.app.net/barmstrong), [barmstrong@app.net](mailto:barmstrong@app.net))
89 |
--------------------------------------------------------------------------------
/layouts/partials/reference_nav.html:
--------------------------------------------------------------------------------
1 |
70 |
71 | ## Resource Configuration
72 |
73 | <%= json(:config) { |h|
74 | user = h["user"]
75 | h.clear
76 | h.update(user)
77 | } %>
78 |
79 | A Resource Configuration object represents values that only apply to a specific App.net resource.
80 |
81 | ### Resource Configuration Fields
82 |
83 |
84 |
85 |
86 |
Field
87 |
Type
88 |
Description
89 |
90 |
91 |
92 |
93 |
annotation_max_bytes
94 |
integer
95 |
The maximum number of bytes that can be attached to this type of object as an Annotation.
96 |
97 |
98 |
text_max_length
99 |
integer
100 |
The maximum number of characters that an instance of this object can be. For User objects, this applies to the User description. This field does not apply to Channel objects.
101 |
102 |
103 |
104 |
105 | ## How to use the Configuration object
106 |
107 | The App.net platform has platform-wide limits that all apps must respect. These limits are enforced at an API level, but can be useful to have defined as constants in your app's code, often for the purpose of displaying your user interface. Examples are things like: "how long can a Post be" or "how long can annotations be on a Channel object." This endpoint allows you to update your app's configuration so it always has the newest platform-wide configuration values available.
108 |
109 | We recommend:
110 |
111 | 1. Ship your application with a static copy of the configuration object. When your app launches for the first time, persist those static values into your application's preference store (NSUserDefaults or SharedPreferences, etc.)
112 | 2. On launch, and at most once per day, poll the configuration endpoint; if it differs from the previously persisted data, update your persisted copy of the configuration object.
113 | 3. Always use the values from your persisted configuration.
114 |
115 | This pattern will ensure that no matter whether your application has network connectivity or not, you will have values, even if they are out of date. As the majority of these variables are related to user interface, slightly outdated configuration variables are generally not a problem.
116 |
117 | This endpoint should be queried with an access token if you have one. If you are creating an app which supports multiple user accounts, you may store this data globally instead of per-user.
118 |
119 | ## Retrieve the Configuration object
120 |
121 | Returns the current Configuration object.
122 |
123 | *Your application should request this endpoint with a user or app access token if available.*
124 |
125 | <%= endpoint "GET", "config", "None" %>
126 |
127 | #### Example
128 |
129 | <%= curl_example(:get, "config", :config) %>
130 |
--------------------------------------------------------------------------------
/content/reference/authentication/flows/web.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Web Flows"
3 | ---
4 |
5 | # Web Flows
6 |
7 | * TOC
8 | {:toc}
9 |
10 | ## Server-side Flow
11 |
12 | This is the easiest way to get an access token—we recommend it to most users of the API. If you're writing an app on a server using a language like Ruby, Python, PHP, Java, etc. you should use this flow.
13 |
14 | **You must keep your `client_secret` confidential**. That means that you may not include it in the source code or binary of an application that you ship to end-users, even in obscured form.
15 |
16 | Your `redirect_uri` must be registered with App.net before you can use it.
17 |
18 | 1. Direct the user that you want to authenticate to this URL:
19 |
20 | https://account.app.net/oauth/authenticate
21 | ?client_id=[your client ID]
22 | &response_type=code
23 | &redirect_uri=[your redirect URI]
24 | &scope=[scopes separated by spaces]
25 |
26 | > To avoid cross-site scripting attacks, we also support the **state** parameter. If you include a state parameter, we will append it to the query parameters when redirecting the user to your **Redirection URI**.
27 |
28 | > To comply with Apple's App Store Guidelines, you can add the query string parameter `adnview=appstore` to hide all signup links on the authentication pages.
29 |
30 | We'll request that the user log in to App.net and show them a permissions dialog allowing them to choose whether to authorize your application.
31 |
32 | > We do not show the permissions dialog if the user has already authorized your application for all scopes in your request, and will instead immediately redirect them. If you wish to force the display of the permissions dialog, use the `https://account.app.net/oauth/authorize` endpoint instead.
33 |
34 | 1. If the user decides to authorize your application, they will be redirected to: `https://[your registered redirect URI]/?code=CODE`
35 |
36 | > If you included a query string in your redirect URI, the `code` parameter will be appended. Likewise, the scheme of your redirect URI will be respected, though we strongly recommend sending all traffic over HTTPS.
37 |
38 | 1. On your server, your application should then make the following request: `POST https://account.app.net/oauth/access_token`
39 |
40 | with URL-encoded POST body:
41 |
42 | client_id=[your client ID]
43 | &client_secret=[your client secret]
44 | &grant_type=authorization_code
45 | &redirect_uri=[your registered redirect URI]
46 | &code=[code received from redirect URI]
47 |
48 | Example:
49 |
50 | <%= curl_example(:post, "access_token", :none, {
51 | :subdomain => "account",
52 | :path_prefix => "/oauth/",
53 | :pretty_json => false,
54 | :token => nil,
55 | :content_type => nil,
56 | :data => {
57 | "grant_type" => "authorization_code",
58 | "client_id" => "[your client_id]",
59 | "client_secret" => "[your client secret]",
60 | "redirect_uri" => "[your registered redirect URI]",
61 | "code" => "[code received in the previous step]"
62 | }
63 | }) %>
64 |
65 | > We also accept the `client_id` and `client_secret` parameters via the Authorization header, as described in [section 2.3.1 of the OAuth 2 spec](http://tools.ietf.org/html/rfc6749#section-2.3.1).
66 |
67 | 1. App.net will respond with a JSON-encoded token: `{"access_token": "[user access token]", "token": {...Token object...}}`
68 |
69 | You can use this access_token to make authenticated calls to the App.net API on behalf of a user.
70 |
71 | ## Client-side Flow
72 |
73 | If you're building a client-side Javascript app or a mobile app that doesn't have an associated back-end server, you'll find that you need to take some special steps to keep your `client_secret` confidential.
74 |
75 | 1. Direct the user that you want to authenticate to this URL:
76 |
77 | https://account.app.net/oauth/authenticate
78 | ?client_id=[your client ID]
79 | &response_type=token
80 | &redirect_uri=[your redirect URI]
81 | &scope=[scopes separated by spaces]
82 |
83 | > To avoid cross-site scripting attacks, we also support the **state** parameter. If you include a state parameter, we will append it to the query parameters when redirecting the user to your **Redirection URI**.
84 |
85 | > To comply with Apple's App Store Guidelines, you can add the query string parameter `adnview=appstore` to hide all signup links on the authentication pages.
86 |
87 | We'll request that the user log in to App.net and show them a permissions dialog allowing them to choose whether to authorize your application.
88 |
89 | > We do not show the permissions dialog if the user has already authorized your application for all scopes in your request, and will instead immediately redirect them. If you wish to force the display of the permissions dialog, use the `https://account.app.net/oauth/authorize` endpoint instead.
90 |
91 | 1. If the user decides to authorize your application, they will be redirected to: `https://[your registered redirect URI]/#access_token=[user access token]`
92 |
93 | > If you included a query string in your redirect URI, the `code` parameter will be appended. Likewise, the scheme of your redirect URI will be respected, though we strongly recommend sending all traffic over HTTPS.
94 |
95 | The access_token will be appended to the URI in the fragment section, encoded as if it were a query string. Your client-side code should parse this for the access_token.
96 |
97 | ## Finishing The Flow
98 |
99 | After you have decided which flow will work for your app you should read our [Web Flow Integration Guide](/reference/authentication/authorize-with-appnet/) to help you integrate the authentication flow into your app.
100 |
101 |
--------------------------------------------------------------------------------
/layouts/partials/endpoints/channel.md:
--------------------------------------------------------------------------------
1 |
127 |
--------------------------------------------------------------------------------
/content/docs/guides/send-a-broadcast.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Broadcasts and the API"
3 | ---
4 |
5 | # Publishing Broadcasts via the API
6 |
7 | <%= access_token_required_note %>
8 |
9 | Broadcast Channels are designed to carry low-volume, high-value updates of interest to users. We call the actual updates themselves Broadcast Messages (or sometimes just "broadcasts"). Because broadcasts are built on top of the existing App.net [Channel](/reference/resources/channel/) and [Message](/reference/resources/message/) APIs, it's helpful to be familiar with them, but for simple tasks, there's not much you need to know.
10 |
11 | Just a reminder: while you can do all of this using our API, you don't have to. We have [tools for publishers](https://broadcast.app.net/manage/) to help you quickly get started pulling content in from elsewhere on the web, and you can send them manually via the web or the App.net iOS and Android apps. To get started, **we recommend that you create and set up your broadcast channel with [our web publisher tools](https://broadcast.app.net/manage/)** and only use the API to send broadcasts via the channel you created.
12 |
13 | ## Send a Broadcast
14 |
15 | There are a number of parts to each broadcast message. To illustrate, here's a screenshot of a broadcast in the App.net iOS app:
16 |
17 | 
18 |
19 | The important parts are the **Headline**, **Photo**, **Text** and **Read More Link**. Everything but the headline is optional, but we recommend that your broadcasts contain a compelling image and some context through a summary text body and a link to content.
20 |
21 | The easiest way to send a broadcast with the API is via the [ADNPy](http://adnpy.readthedocs.org) Python module, the [adn](https://github.com/adn-rb/adn) Ruby gem, the [appnet.js](https://github.com/duerig/appnet.js) library for Node.js, or the [AppDotNetPHP](https://github.com/jdolitsky/AppDotNetPHP) library. You can also use the HTTP API with your own client, if you'd like.
22 |
23 | Starting with Python, here's an example of using the ADNPy `BroadcastMessageBuilder` recipe. If you're interested in the specific API calls the library is making behind the scenes, [look at the source](https://github.com/appdotnet/ADNpy/blob/master/adnpy/recipes/broadcast.py).
24 |
25 | Once you've installed the ADNPy library, it's as simple as:
26 |
27 | ~~~ python
28 | import adnpy
29 |
30 | # Set the default access token for API calls.
31 | adnpy.api.add_authorization_token('')
32 |
33 | # Send a broadcast with the BroadcastMessageBuilder recipe.
34 | builder = adnpy.recipes.BroadcastMessageBuilder(adnpy.api)
35 | builder.channel_id = 24204 # Get this channel ID from the web publisher tools
36 | builder.headline = 'Hello World!'
37 | builder.text = 'Sending this from [ADNPy](https://github.com/appdotnet/ADNPy) was easy!'
38 | builder.parse_markdown_links = True
39 | builder.read_more_link = 'http://adnpy.readthedocs.org/'
40 | builder.send()
41 | ~~~
42 |
43 | You can easily attach a photo:
44 |
45 | ~~~ python
46 | builder.photo = '/home/paul/celeryman.gif'
47 | ~~~
48 |
49 | Or with the [adn](https://github.com/adn-rb/adn) Ruby gem:
50 |
51 | ~~~ ruby
52 | require 'adn'
53 |
54 | ADN.token = ''
55 |
56 | builder = ADN::Recipes::BroadcastMessageBuilder.new
57 | builder.channel_id = 24204
58 | builder.headline = 'sending from ruby'
59 | builder.read_more_link = 'https://app.net'
60 | builder.photo = '/home/mthurman/oyster-smiling.png'
61 | builder.send
62 | ~~~
63 |
64 | If you want to send the equivalent broadcast from the API without using a library, use this curl command:
65 |
66 | <% data = {
67 | "text" => "Here is a [link](http://www.google.com) for my text body.",
68 | "annotations" => [{
69 | "type" => "net.app.core.broadcast.message.metadata",
70 | "value" => {
71 | "subject" => "Hello world!"
72 | },
73 | },
74 | {
75 | "type" => "net.app.core.crosspost",
76 | "value" => {
77 | "canonical_url" => "http://www.example.com"
78 | },
79 | }],
80 | "entities" => {
81 | "parse_markdown_links" => true,
82 | "parse_links" => true
83 | }
84 | } %>
85 | <%= curl_example(:post, "channels/24204/messages?include_annotations=1", :none, {:data => data}) %>
86 |
87 |
88 | ## Create a Broadcast Channel
89 |
90 | You can create broadcast channels with the API as well.
91 |
92 | Broadcast channels are created like any other channel, with a specific type value (`net.app.core.broadcast`) and a few special annotations. For information on creating channels, see the [Channel lifecycle documentation](/reference/resources/channel/lifecycle/). Broadcast channels fully support [ACLs](/reference/resources/channel/) for private applications.
93 |
94 | Here is an example channel body, set to be public, with multiple editors, which you can POST to us:
95 |
96 | <% data = {
97 | "type" => "net.app.core.broadcast",
98 | "readers" => {
99 | "public" => true
100 | },
101 | "editors" => {
102 | "user_ids" => ["@samsharp", "@sfborscht"]
103 | },
104 | "annotations" => [{
105 | "type" => "net.app.core.broadcast.metadata",
106 | "value" => {
107 | "title" => "SF Borscht Truck Updates",
108 | "description" => "Get a notification when the SF Borscht Food Truck will be on the streets!"
109 | }
110 | }]
111 | } %>
112 | <%= json_output(data) %>
113 |
114 | Here's a sample curl command that'll create a channel:
115 |
116 | <%= curl_example(:post, "channels?include_annotations=1", :none, {:data => data}) %>
117 |
118 | This will return a fully-populated channel resource, including the `id` of the channel, a few auto-generated annotations, and the `fallback_url`, which is the short URL for the channel's detail page.
119 |
120 | <%= response(:channel) do |h|
121 | h["data"]["recent_message"] = nil
122 | h["data"]["recent_message_id"] = nil
123 | h["data"]["counts"]["messages"] = 0
124 | h["data"]["counts"]["subscribers"] = 1
125 | data["annotations"] << {
126 | "type" => "net.app.core.broadcast.freq",
127 | "value" => {
128 | "avg_freq" => "less than 1 per week",
129 | "intensity" => 0.1
130 | }
131 | }
132 | data["annotations"] << {
133 | "type" => "net.app.core.fallback_url",
134 | "value" => {
135 | "url" => "https://app.net/c/2rds"
136 | }
137 | }
138 | data["annotations"][0]["value"]["tags"] = []
139 | h["data"]["annotations"] = data["annotations"]
140 | h["data"]["type"] = data["type"]
141 | h["data"]["editors"]["user_ids"] = ["190151", "190195"]
142 | end %>
143 |
--------------------------------------------------------------------------------