Podling API Documentation

Introduction

Most of Podling's functionality can be accessed via its JSON over HTTPS API. The API is known as “the86”.

Each user has an authentication token which can be used to make API requests. A valid username and password can be exchanged for this API access token.

API URL paths include the major version number of the API, and a path to the resource (item or collection). For example, /api/v1/groups/test-group/conversations/123/posts represents the collection of Posts in a Conversation. It responds to GET and POST requests to list and create Posts, respectively.

Back to top

Clients

While the HTTP API is simple enough to use directly in many cases, there are open source client libraries available for Ruby and PHP.

Let us know if you've written one for your language or platform of choice, and we'll add it to the list.

# The domain running The 86 discussion server.
The86::Client.domain = "the86.yourdomain.com"

# HTTP Basic Auth credentials allocated for your API client.
The86::Client.credentials = ["username", "password"]

# Create an end-user account:
user = The86::Client.users.create(name: "John Citizen")
oauth_token = user.access_tokens.first.token

# Create a new conversation:
conversation = The86::Client.site("example").conversations.create(
  content: "Hello world!",
  oauth_token: oauth_token
)

# Check for updates:
site = The86::Client.site("example")
conversations = site.conversations.with_parameters(
  posts_since: time.iso8601,
  without_user: 64,
)
<?php

// Get a configured client.
$client = The86\The86Client::factory(array(
  'domain' => 'the86.example.org',
  'username' => 'your-group-username',
  'password' => 'your-group-password',
));

// Create a User.
$user = $client->getCommand('CreateUser', array(
  'attributes' => array(
    'name' => 'John Citizen',
  ),
))->execute();
var_dump($user->access_tokens[0]->token); // Keep it secret. Keep it safe.

// Create a Conversation.
$conversation = $client->getCommand('CreateConversation', array(
  'group' => 'example',
  'oauth_token' => 'usersoauthtoken',
  'attributes' => array(
    'content' => 'Hello world!',
  ),
))->execute();
$post = $conversation->posts[0];
var_dump($post->content_html); // HTML, auto-linkified, etc.

// List all recent conversations/posts for a group.
$conversations = $client->getCommand('ListConversations', array(
  'group' => 'example',
  'parameters' => array(
    'posts_since' => '2012-08-08T03:26:52Z',
  ),
))->execute();
Back to top

Versioning

Podling's API attempts to adhere to Semantic Versioning, with the major X component of the X.Y.Z version number exposed in the URL path.

An example of a version one API URL is: https://podling.com/api/v1/users/3

If and when the major version component is incremented, representing non-backwards-compatible changes, the previous version should be supported for a reasonable period of time.

Back to top

Authentication

Authentication is implemented using OAuth 2.0 Bearer Tokens in the Authorization HTTP header.

This is not a full implementation of OAuth 2.0. Only the name and format of the Authorization header is used. API clients must obtain this authentication token via a non-OAuth-2.0 method.

Attempting an API request without the required Authentication header will result in a `401 Unauthorized` response.

Attempting an API request not permitted by the provided Authentication header will result in a `403 Forbidden` response.

An email address and password may be exchanged for a user_access_token to be used as a bearer token by POSTing to /api/v1/users/authenticate.

POST /api/v1/users/authenticate HTTP/1.1
Host: podling.com
Content-Type: application/json; charset=utf-8
Accept: application/json
User-Agent: HTTPie/0.2.7dev

{
    "email": "john@example.org",
    "password": "secret"
}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Etag: "dd60d92e26130f2437e6530870d228bd"
Cache-Control: max-age=0, private, must-revalidate
Date: Tue, 26 Feb 2013 01:26:51 GMT
Content-Length: 455

{
    "user": {
        "avatar_url": "https://api.twitter.com/1/users/profile_image/johncitizen",
        "created_at": "2012-10-25T10:44:45Z",
        "email": "john@example.org",
        "id": 123,
        "location": "Melbourne, Australia",
        "name": "John Citizen",
        "profile": "Just a regular citizen",
        "twitter_username": "johncitizen",
        "url": "https://podling.com/api/v1/users/123"
    },
    "user_access_token": "q-IdfBsampletokenziKTMxQ7zZ1zzt-JWd2oAXLp13"
}
Back to top

Errors

Error responses are represented by a suitable HTTP code (e.g. 404 Not Found or 422 Unprocessable Entity) and a JSON response body containing a message attribute.

Some types of error will extend this response body with additional attributes.

Validation Errors

A validation error encountered while creating a resource is represented by a 422 Unprocessable Entity response.

For each validation error that occured, the errors array in the response JSON container a resource name, field name and message.

POST /api/v1/users/123 HTTP/1.1
X-Http-Method-Override: PATCH
Host: podling.com
Accept: application/json
Content-Type: application/json; charset=utf-8
User-Agent: HTTPie/0.2.7dev
Authorization: Bearer q-IdfBsampletokenziKTMxQ7zZ1zzt-JWd2oAXLp13

{
    "name": ""
}
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache
Date: Tue, 26 Feb 2013 00:40:10 GMT
Content-Length: 105

{
    "errors": [
        {
            "field": "name",
            "message": "can't be blank",
            "resource": "User"
        }
    ],
    "message": "Validation failed."
}
Back to top

Representations

Resources are represented as JSON; either a single object, or an array of objects. The representation of a resource may contain nested child and parent resources.

Collections may be paginated. This is indicated by the rel="next" item of the Link HTTP header, which provides the URL of the next page in the collection. The presence of this header means there is another page, the absence means there is not.

This is a (truncated) example of a paginated collection of Conversations. The outer data type is a JSON array. The Link HTTP header points to the next page in the collection. Each conversation contains an array of Posts (in this case, only one). Each Post contains subresources such as Likes, and a representation of the User that created the Post.

GET /api/v1/groups/abc/conversations HTTP/1.1
Authorization: Bearer AUTH_TOKEN_HERE
Host: podling.com
Accept-Encoding: identity, deflate, compress, gzip
Accept: */*
User-Agent: HTTPie/0.2.7dev
HTTP/1.1 200 OK
Link: <https://podling.com/api/v1/groups/abc/conversations?bumped_before=2012-11-14T04%3A13%3A09Z>; rel="next"
Content-Type: application/json; charset=utf-8
Etag: "30888cf59c9c7b7faac5ed55d9d69b80"
Cache-Control: max-age=0, private, must-revalidate
Vary: Accept-Encoding
Server: 
Date: Mon, 25 Feb 2013 06:46:04 GMT
Content-Length: 

[
  {
    "bumped_at": "2013-02-12T05:52:42Z",
    "created_at": "2013-02-12T05:52:42Z",
    "id": 2079,
    "posts": [
      {
        "attachments": [],
        "content": "Test",
        "content_html": "<p>Test</p>",
        "created_at": "2013-02-12T05:52:42Z",
        "id": 8743,
        "in_reply_to_id": null,
        "is_original": true,
        "likes": [],
        "updated_at": "2013-02-12T05:52:42Z",
        "user": {
          "avatar_url": null,
          "created_at": "2013-02-06T04:37:35Z",
          "email": "john@example.org",
          "id": 5479,
          "location": null,
          "name": "John Citizen",
          "profile": null,
          "twitter_username": null,
          "url": "https://podling.com/api/v1/users/5479"
        }
      }
    ],
    "updated_at": "2013-02-12T05:52:42Z"
  }
]
Back to top