Welcome to the API documentation for Microco.sm. On this single-page site we explain how to use the Microco.sm API. Print this page or bookmark, just keep it handy.

The Microco.sm API is a RESTful API. We acknowledge that the users of an API are the developers who implement against the API, and with that in mind we have sought to make pragmatic choices that help and assist you, the developer. We offer an API that we believe has the best of REST without limiting the ways in which you may implement a solution using our API.

Using the API is as easy as:

curl -X GET https://dev1.microco.sm/api/v1/microcosms

What we give you:

  • A JSON interface of resources that you can manipulate via the most common HTTP verbs.
  • Token-based authentication to identify the user and client accessing the API.
  • Resources that compose together enough data (including links, associated data, and metadata) that you can do what you need with a minimal number of API calls.
  • HATEOAS inspired meta data to show the relation of a given resource to other resources, as well as a description of your user's permissions so that you know what state changing actions your user can perform.

Deviations from pure REST and HATEOAS:

  • We allow HTTP methods to be overridden.
  • We include support for callbacks (including JSONP), which means that our responses include meta data in addition to the resource itself.
  • We haven't created unique content types for each resource, we just use application/json.
  • We put our API version information in the URL rather than the HTTP headers.
  • We only serve JSON.

Because of those deviations we are not a pure REST API (the lack of custom content types took care of that), and we are not a pure HATEOAS interface (the lack of XML-only support took care of making the links less discoverable). However, we do think that for the majority of developers these design decisions will help make the API easier to implement against.

The next bit covers conventions and standards within the API, if you just want to get to the nitty gritty and make an API call, then jump the conventions and go straight to the /site API to make your first call.

API Flow

At the highest level you can imagine that the core flow through the API is this: Image showing the high level flow through the API.

Sites have Microcosms. Microcosms have types of content that include Conversations, Events and Polls. Those types of content can additionally have Comments. Sites also have Profiles, and as a convenience method we provide WhoAmI to redirect you to the profile of the authenticated user.

That is overly simplistic, of course; Comments are made by Profiles, and an Event describes which Microco.sm it is in, etc. but as a high-level view it suffices.

Terminology

If you're coming from other forum/community software then you can translate things in this way:

Common Terminology Microco.sm Terminology Differences
Forum Site

In vBulletin, phpBB, and so on, the 'forum' is the over-arching instance of the software and the software runs on a single web domain.

Microco.sm being a platform can power thousands of web domains with the same software, and a single web domain is just one 'site' on this platform.

Forums or subforums Microcosms

Within traditional forum software many forums can exist and they may be nested (subforums inside forums). These 'forums' are created by administrators and the users create conversations within an individual forum.

We have Microcosms instead of forums, and these are provided as a list rather than a tree-structure. The name Microcosm was chosen as they can contain everything a group may need, the events, polls, conversations, etc... they represent a smaller microcosm of the whole community.

Users are able to create these Microcosms, the structure of the site is not necessarily dictated by the site administrator.

Threads Conversations

Threads are the bread and butter of a traditional forum, and within a Microcosm we have a conversation as the direct equivalent.

A conversation is simply a collection of comments on a topic.

Posts Comments

Within traditional forum software threads have posts, and that's it.

Microco.sm has comments that exist within a conversation, but additionally other types of content like an event or poll can also have comments.

Comments are pieces of user generated content attached in the form of a list to some other content.

Boiler Plate

Our responses are wrapped in boiler plate JSON that helps to describe what has happened. The purpose of this is to support callbacks, provide a really simple way of getting error/success information, and to additionally support the use of JSONP to those who need it.

All responses are wrapped in this:

{
  "context": "",
  "status": 200,
  "data": null
  "error": null
}
  • context = A string value given to the API via the querystring ?context=foo would be returned to you here. This enables you to make asynchronous callbacks and to include a token that can identify which request this response relates to.
  • status = The integer HTTP status of the response. You should use the HTTP header status, this is provided to help JSONP requests.
  • data = The actual JSON representation of the resource requested.
  • error = An array of strings that contain any error messages. If error is null, then no error has occurred.

All of the above will be returned on every call, null and "" are used to represent an absense of data (no context supplied, no data retrieved, and no error).

The boiler plate can be disabled by ensuring disableBoiler is set in the querystring like this: /api/version/resource?disableBoiler or within a HTTP header like this: X-Disable-Boiler: true. With either of those set only the data object would be returned in the body of the response.

HTTP Status Codes

We only return a few HTTP status codes that generally describe the state of a request, your application need only handle these status codes:

HTTP Status Description
200 OK Standard response for successful HTTP requests.
301 Permanently Moved The requested resource is now to be found at the location described in the HTTP Location header, all future requests should be sent to that URL.
302 Found The requested resource is now to be found at the location described in the HTTP Location header. After using a POST or UPDATE we may return a 302 to point you to the newly created resource. Your client should follow HTTP redirects, but future requests should not cache this redirect and should be sent to the original location.
303 See Other The response to the request can be found under another URL using a separate GET method. When received in response to a POST (or PUT/DELETE), it should be assumed that the server has received the data OK and the new GET request starts a new request chain.
400 Bad Request The client has made a bad request, which includes requests with malformed JSON, or invalid data values as well as requests in which the URL contains incorrect values (such as providing a string for an ID when an integer is expected).
401 Unauthorized You lack the permission to do whatever you were trying to do. But, if you are able to authenticate as a user with that permission then you will be allowed to do this. That is, if your user is not logged in then prompt them to login, or if your user is logged in then they may need a different user or a higher privileged user to perform the task for them (such as editing content owned by someone else).
403 Forbidden You aren't allowed to do what you were trying to do, and logging in is not going to help you. For example, you are not allowed to delete a whole collection of resources.
404 Not Found We cannot find what you requested, though the request looks good. Note that we do not differentiate between resources that have never existed and ones that once existed but are now deleted... if we can't return it to you, then we return 'not found'.
405 Method Not Allowed A request was made of a resource using a request method not supported by that resource; for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.
500 Server Error Something bad has happened at our end and it's not your fault. You made a good request, but we've failed you. Please try again later, or send us a bug report: hello@microcosm.cc with an example of both the request and response and we will definitely look into it.
501 Not Implemented The server either does not recognize the request method, or it lacks the ability to fulfill the request. This is a very rare event and should not happen in normal circumstances, but may happen if we add a basic functionality for a new feature and a request is made to some unimplemented part of that feature.

Callbacks

We support callbacks using JSONP. To achieve that 3 things are needed:

  1. The ability to wrap the returned JSON in a callback function.
  2. The ability to override the HTTP method so that you can perform the action of HTTP PUT and HTTP DELETE via HTTP POST.
  3. The ability to only ever return a HTTP 200 OK status.

To fulfil the first requirement you can wrap the response in a callback function name you provide by adding callback=funcName to the querystring of your request.

To fulfil the second requirement you can overload the HTTP method by making a HTTP POST request and adding method=PUT or method=DELETE as necessary to the querystring. You also have the option to use the standard X-HTTP-Method-Override HTTP header.

Note: If you are not using JSONP or have not proven that you require HTTP method overriding, then please do not do this. Instead just use the correct HTTP verb when you make your request. HTTP PUT and DELETE are idempotent whereas HTTP POST is not, and this can create issues.

To fulfil the third requirement you may add always200 to the querystring or X-Always-200: true to the HTTP headers and this will force the API to only ever return a HTTP 200 OK header regardless of what happened. The status property in the boiler plate JSON will still give the underlying HTTP status code so that you can handle the response appropriately.

This means that to make a JSONP request for GET and POST, you merely have made a request similar to /api/version/resource?always200&callback=funcName and for PUT and DELETE you have additionally added &method=PUT or &method=DELETE as necessary to the querystring.

Note: You should not combine disableBoiler with the JSONP features, as the API will only ever be returning HTTP 200 OK, and you will need to check the status property of the boiler plate.

You are also able to provide context via the querystring and whatever the value of that parameter is will be provided back to you in the context property of the boiler plate.

URL Patterns

The base path of the API is https://{subdomain}.microco.sm/api/v1. Even if a site has a CNAMEd domain such as http://example.com , the API will always be served over SSL on a {subdomain}.microco.sm URL. All resources are children of that base path. Throughout this documentation you will see that base path written in shorthand as /api/v1.

There are two patterns of URLs, and which is used is determined by whether the resource name in the URL is pluralised or not. Resources that are pluralised represent collections /api/v1/things, and resources that are not pluralised represent a single resource /api/v1/thing.

Single resources tend to be descriptive meta-data only and will usually only respond successfully to a GET request.

Resource URLs never end in a trailing slash, as resources are themselves the entity you operate on, and a trailing slash would indicate a directory on the web server.

URLs and actions for a resource collection:

HTTP Method URL Pattern Description
GET /api/v1/things Returns a collection of the resource called 'things'.
PUT /api/v1/things Collection updating is largely forbidden, would return HTTP 403. Please update individual resources.
DELETE /api/v1/things Collection deletion is largely forbidden, would return HTTP 403. Please delete individual resources.
POST /api/v1/things Would create a new resource 'thing' and return a 301 to the GET method for the newly created 'thing'.
GET /api/v1/things/{id} Would read a single 'thing' for the given {id}.
PUT /api/v1/things/{id} Would update a single 'thing' for the given {id}.
DELETE /api/v1/things/{id} Would delete a single 'thing' for the given {id}.

URLs and actions for a single resource:

HTTP Method URL Pattern Description
POST /api/v1/thing Create the resource. May be forbidden depending on the type of resource and the permissions derived from your access token.
GET /api/v1/thing Read the resource.
PUT /api/v1/thing Update the resource. Likely to be forbidden in a single resource context as this tends to be a read-only resource unless you are the owner of the content.
PATCH /api/v1/thing Update part of the resource. Where this is available we use the format specified in RFC 6902 to describe a list of operations that can modify the resource. We only support the replace operation, which allows you to make a request to replace a given value in the resource without needing knowledge of the whole resource.
DELETE /api/v1/thing Delete the resource. Likely to be forbidden in a single resource context as this tends to be a read-only resource unless you are the owner of the content.

Note: If you add trailing slashes then the API returns a 404 Not Found response. Resources are not directories.

Pagination

Pagination of collections is supported using the offset approach:

  • limit = /api/v1/things?limit=10 would return up to 10 'things'.
  • offset = /api/v1/things?offset=50 would return up to the default number of 'things' starting at the 50th record.
  • limit with offset = /api/v1/things?limit=10&offset=30 would return up to 10 'things' starting at the 30th record.

The default value for limit is 25, and the default value for offset is 0. Meaning that if you do nothing, then you will get up to 25 records at the beginning of the collection.

The format of our collections is consistent, all resources that return a collection of resources will do so using this structure:

"collectionName": {
  "total": 861,
  "limit": 10,
  "offset": 100,
  "maxOffset" 860,
  "totalPages": 87,
  "page": 11,
  "links": [
    {"rel": "first", "href": "/api/v1/things?limit=10"},
    {"rel": "prev", "href": "/api/v1/things?limit=10&offset=90"},
    {"rel": "self", "href": "/api/v1/things?limit=10&offset=100"},
    {"rel": "next", "href": "/api/v1/things?limit=10&offset=110"},
    {"rel": "last", "href": "/api/v1/things?limit=10&offset=860"},
  ],
  "type": "/api/v1/things",
  "items": [
    ...
  ]
}

Where:

  • collectionName = Will be replaced with the name of the collection.
  • total = The total number of resources in the collection.
  • limit = The maximum number of resources per page of the collection.
  • offset = The current offset in the query.
  • maxOffset = The maximum offset that will return a page.
  • totalPages = The total number of pages in the collection.
  • page = The current page in the collection.
  • links = A pre-calculated array of links to navigate the collection. If you are on the last page then you will not receive the "rel": ["next"] link, and likewise if you are on the first page you will not receive the "rel": ["prev"]
  • type = Describes the type of record in the items array.
  • items = Contains the resources being paginated.

Note: A 400 Bad Request will be returned if: limit is not divisible by 5, offset is not a multiple of the limit, or the use of offset would navigate to a page outside of the bounds of the collection.

Resource Metadata

Most of the API calls will return a JSON object called meta, as part of the data object, that looks like this:

"meta":{
   "created": "2013-04-11T05:52:46.362755Z",
   "createdBy": {
      "id": 1,
      "userId": 1,
      "profileName": "BillyPilgrim",
      ...
   },
   "flags": {
      "sticky": false,
      "open": true,
      "deleted": false,
      "moderated": false,
      "visible": false,
      "unread": true
   },
   "links":[
      {"rel":"self", "href":"/api/v1/site"},
      {"rel":"microcosm", "href":"/api/v1/microcosms"},
      {"rel":"profile", "href":"/api/v1/profiles"}
   ],
   "permissions":{
      "create":false,
      "read":true,
      "update":false,
      "delete":false,
      "guest":true,
      "superUser":false
   }
}

Author Information

Where applicable (single items), author information will be presented in the form of:

Property Type Description
created ISO8601 Datetime When the resource was created.
createdBy Profile summary object Who created the resource and a link to that profile.
edited ISO8601 Datetime If the resource has been modified since creation, when the resource was last modified.
editedBy Profile summary object If the resource has been modified since creation, who modified the resource most recently and a link to that profile.
editReason String If the resource has been modified since creation, a one-line summary of the most recent modification.

Flags

Where applicable (single items), generic boolean flags will be presented in a flags object:

Property Type Description
sticky bool Whether the item is stuck to the top of any lists of items. That is, a stuck Microco.sm would appear before all unstuck Microcosms in the list of Microcosms.
open bool Whether the item is can be POSTed to. That is, an open conversation can receive new comments as replies, whereas a closed conversation still has existing comments but is not accepting new comments.
deleted bool Whether the item is deleted. For most users these will not be visible, but for super users these may be visible and may be undeletable.
moderated bool Whether the item is in the moderation queue awaiting approval (to be unmoderated) or rejection (to be unmoderated but deleted).
visible bool Summarises deleted and moderated into a single flag indicating whether the resource is currently visible on the site to most users.
unread bool If the item has previously been read before by the user. The user needs to be logged in otherwise this will return false. An item (conversation, event, poll) is marked as read if the user has read all comments in it, and a microcosm is marked as read if all items within it are read.

The links array contains a list of hypermedia links. The rel property describes the relation of the link to the object that this meta object is attached to. The example above is taken from the /site API and shows that the link to itself is at /api/v1/site, and the link to Microcosms can be found at /api/v1/microcosms.

Links are there to describe to you the most obvious navigation actions that you can now perform given the context of the request and to provide you with that link so that you do not have to construct it yourself.

We currently support the following link relations:

Relation Description
self Indicates that the containing object contains a resource equivalent to the one found at the href URL. Basically: A link to itself.
first In a pagination collection, refers to the resource furthest preceding the current resource.
prev In a pagination collection, refers to the resource directly preceding the current resource.
next In a pagination collection, refers to the resource directly following the current resource.
last In a pagination collection, refers to the resource furthest following the current resource.
comment Refers to a resource that can be found within the /api/v1/comments URL or it's child resources.
conversation Refers to a resource that can be found within the /api/v1/conversations URL or it's child resources.
event Refers to a resource that can be found within the /api/v1/events URL or it's child resources.
microcosm Refers to a resource that can be found within the /api/v1/microcosms URL or it's child resources. In the case of a link to a single Microco.sm it will usually also include the optional 'title' property to give a displayable name of the linked resource.
poll Refers to a resource that can be found within the /api/v1/polls URL or it's child resources.
profile Refers to a resource that can be found within the /api/v1/profiles URL or it's child resources.
site Refers to the resource that represents the current site and that can be found at the /api/v1/site URL.

Permissions

Permissions on the other hand are there to describe to you the data-changing actions you can perform to the resource in the current context. You should interpret permissions alone these lines:

Permission Description
create Whether you can perform a POST request in this context, and therefore whether you have permission to add resources to a collection.
read Whether you can perform a GET request in this context. This will always be true, as you will have received a 401 or 403 error if you did not have permission to read this resource.
update Whether you can perform a PUT request in this context. The general guideline is that you can only update your own content, unless you are authenticated as a super user.
delete Whether you can perform a DELETE request in this context. In general, you can only delete your own content, unless you are authenticated as a super user.

The permissions themselves are always at the site level, microcosm level, or the item level. That is, if you are the owner of an item by virtue of authoring it, then you have certain permissions that stem from that. Otherwise your permissions are derived from a Microcosm (if the API call relates to something that relates to a Microcosm, or from the site.

Be sure to reflect this information within your client so that a user doesn't try to edit content when they will not have permission to do so.

Authentication

We use Mozilla Persona to authenticate users. This supplies us with a verified email address for each user but doesn't require any other personal information. When a user logs in with Persona, you (the API client) are provided with an Assertion for the user which signifies that the user has successfully logged in to your application.

You can read about assertions on the Persona website or view example code.

When you sign up as an API client we will provide you with a client secret. This is used in conjunction with a Persona assertion to generate an access token for a user.

To generate an access token, POST the following structure to /auth.

{
  "Assertion": "suppliedByPersonaOnUserLogin",
  "ClientSecret": "suppliedByMicrocosmDuringDevClientRegistration"
}

Where:

Property Type Optional? Description
Assertion String Required Assertion from Mozilla Persona signifying a successful user login for the site.
ClientSecret String Required Client secret supplied when the API client was registered with Microco.sm.

Example request

curl -i \
-X POST \
-H "Content-Type: application/json" \
-d '{"Assertion": "redacted", "ClientSecret": "redacted"}' \
https://dev1.microco.sm/api/v1/auth

Example response

{
    "status": 200,
    "data": "theGeneratedAccessTokenToAuthenticateFutureRequestsByThisUser",
    "context": "",
    "error": null
}

The data attribute above contains a string which is the generated access token. You can supply this with a request to the API to authenticate the user.

Access tokens can be supplied as an HTTP header in the form Authorization: Bearer {access_token} or in the querystring in the form access_token={redacted}. If both header and querystring are provided, only the header will be examined. The header is the recommended way of providing the access token, the query string is made available to help support some clients which may not have access to the HTTP headers but the use of this is not encouraged.

Tokens do not currently expire, nor do they have a particular scope. These are earmarked for future development as is allowing users to revoke older access tokens whilst logged in with a more recent access token.

Error Handling

As a developer implementing against the API, you must rely on the HTTP status codes returned to handle errors.

If an error has occurred we will additionally inform you, the developer, of the cause of the error by populating the error property of the boiler plate. The error property holds an array of strings to help you, the developer, to fix the issue.

Note: The audience of the error string array is the developer implementing against the API. Please take care not to send error messages to the end user. Instead handle it in some elegant way in the UI that you present to the end user. To emphasise this: the error text is not localised, it will always be in English, it is designed to be understood by a developer and not an end user, it may change over time to be clearer to developers how to fix the error. Bottom line: Rely on HTTP status codes and nothing else.

An example error (in this case for an invalid authentication access token):

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
   "context":"",
   "status":403,
   "data":null,
   "error":[
      "You have supplied an invalid access token"
   ]
}

Note: If you are making JSONP requests and are making use of the always200 flag, then you must look at the status property in the JSON response to ensure that you do not silently ignore errors.

We do not yet have a tutorial to share, but it is a TODO on our tasklist and we will prepare one before the public launch.

/site

Provides information about the site that you are currently on: the name of the site, the site logo, who created the site, and who owns the site.

URLs and Methods

URL Pattern Method Description
/api/v1/site OPTIONS The Allow: header lists the methods available.
/api/v1/site GET Returns information about the current site.

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/site

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 14:12:26 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET

GET

There are no query string paramaters, the response of this API call describes the basic properties of a web site.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/site

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 14:12:57 GMT
Content-Type: application/json
Content-Length: 1716
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "siteId": 1,
  "title": "Middle Earth",
  "description": "Middle Earth is the central continent of the world in the third age.",
  "subdomainKey": "dev1",
  "domain": "",
  "ownedBy": {
   "id": 1,
   "siteId": 1,
   "userId": 1,
   "profileName": "Frodo",
   "visible": true,
   "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
   "meta": {
    "links": [
     {
      "rel": "self",
      "href": "/api/v1/profiles/1"
     },
     {
      "rel": "site",
      "href": "/api/v1/sites/1"
     }
    ]
   }
  },
  "themeId": 1,
  "logoUrl": "https://dev1.microco.sm/api/v1/files/30ff6e4d33e1ff64deb3cc6f2be8a97e8abaa77f",
  "headerBackgroundUrl": "/static/themes/1/background.png",
  "meta": {
   "created": "2013-11-21T11:34:01.857651Z",
   "createdBy": {
    "id": 1,
    "siteId": 1,
    "userId": 1,
    "profileName": "Frodo",
    "visible": true,
    "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/1"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/sites/1"
    },
    {
     "rel": "microcosm",
     "href": "/api/v1/microcosms"
    },
    {
     "rel": "profile",
     "href": "/api/v1/profiles"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

/microcosms

Provides an interface to the microcosms that exist on a site and information on the items contained within them.

Conceptually a microcosm can be imagined as being like a 'forum' or 'sub-forum' on a traditional piece of forum software. The reason it is called a microcosm rather than a forum is that it is a container for all conversations, polls, and other resources such as events. In that regard it offers the full capabilities and features of the site within a small part of the site... a microcosm.

URLs and Methods

URL Pattern Method Description
/api/v1/microcosms OPTIONS The Allow: header lists the methods available.
/api/v1/microcosms POST Creates a new microcosm on the current site.
/api/v1/microcosms GET Returns information about the microcosms that exist on the current site.
/api/v1/microcosms/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/microcosms/{id:[0-9]+} GET Returns information about the microcosm specified by the numeric identifier and a collection of items related to this microcosm.
/api/v1/microcosms/{id:[0-9]+} PUT Updates the microcosm specified by the numeric identifier.
/api/v1/microcosms/{id:[0-9]+} DELETE Deletes the microcosm specified by the numeric identifier.
/api/v1/microcosms/markread OPTIONS The Allow: header lists the methods available.
/api/v1/microcosms/markread PUT Marks the microcosm and all children items as read.

The microcosmId is based on a sequential number (that spans all sites in the microcosm network). You should not make any assumptions in your code that on a given site the identifiers will be contiguous (that the existence of id=17 infers the existence of id=16, id=15, etc on that site).

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/microcosms

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 14:45:58 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST,HEAD,GET

POST

Request:

The structure of the JSON to create a Microco.sm is:

{
   "title": "Rivendell",
   "description": "Refuge of the Elves, the House of Elrond lies within."
}

Where:

Property Type Optional? Description
title String Required A short textual name for the microcosm, displayed everywhere the microcosm is mentioned. Should be as terse, yet descriptive as possible.
description String Required A single line of text that provides information on the microcosm and provides the definition of what content is on-topic within the microcosm.
visibility String Optional Must be one of 'public', or 'protected'. Where 'public' allows the microcosm to be accessed without limitation and be discoverable across other sites, 'protected' allows the microcosm to be found and displayed in the context of the current site. If no value is supplied, this defaults to 'public'.

Example request:

curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"title":"Rivendell", "description":"Refuge of the Elves, the House of Elrond lies within."}' \
  https://dev1.microco.sm/api/v1/microcosms

Example response:

HTTP/1.1 302 Found
Date: Thu, 21 Nov 2013 14:53:29 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/microcosms/2

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly created microcosm.

GET

Fetches a collection of microcosms. If a valid access_token is provided then the collection may contain microcosms not visible to guests or that are private.

Request:

The pagination query string parameters allow you to paginate the collection of microcosms returned:

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/microcosms

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 14:55:26 GMT
Content-Type: application/json
Content-Length: 3046
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "microcosms": {
   "total": 2,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/microcosms"
    }
   ],
   "type": "/api/v1/microcosms",
   "items": [
    {
     "id": 1,
     "siteId": 1,
     "visibility": "public",
     "title": "The Shire",
     "description": "Growing vegetables, brewing ale and smoking weed",
     "moderators": null,
     "totalItems": 0,
     "totalComments": 0,
     "mostRecentUpdate": null,
     "meta": {
      "created": "2013-11-21T13:20:32.823424Z",
      "createdBy": {
       "id": 5,
       "siteId": 1,
       "userId": 3,
       "profileName": "Gandalf",
       "visible": true,
       "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/5"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "flags": {
       "sticky": false,
       "open": true,
       "deleted": false,
       "moderated": false,
       "visible": false,
       "unread": false,
       "watched": false
      },
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/microcosms/1"
       },
       {
        "rel": "site",
        "href": "/api/v1/sites/1"
       }
      ]
     }
    },
    {
     "id": 2,
     "siteId": 1,
     "visibility": "public",
     "title": "Rivendell",
     "description": "Refuge of the Elves, the House of Elrond lies within.",
     "moderators": null,
     "totalItems": 0,
     "totalComments": 0,
     "mostRecentUpdate": null,
     "meta": {
      "created": "2013-11-21T14:53:29.638086Z",
      "createdBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/1"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "flags": {
       "sticky": false,
       "open": true,
       "deleted": false,
       "moderated": false,
       "visible": false,
       "unread": false,
       "watched": false
      },
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/microcosms/2"
       },
       {
        "rel": "site",
        "href": "/api/v1/sites/1"
       }
      ]
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/microcosms"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/microcosms/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 15:05:24 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET,PUT,PATCH,DELETE

GET

Fetches the detailed information about a single microcosm, including a collection of items contained within the microcosm. The pagination query string parameters allow to you traverse the collection of items. Items include conversations, events, polls, etc.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/microcosms/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 15:05:52 GMT
Content-Type: application/json
Content-Length: 1533
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "id": 1,
  "siteId": 1,
  "visibility": "public",
  "title": "The Shire",
  "description": "Growing vegetables, brewing ale and smoking weed",
  "moderators": null,
  "items": {
   "total": 0,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 0,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/microcosms/1"
    }
   ],
   "type": "/api/v1/comments",
   "items": []
  },
  "meta": {
   "created": "2013-11-21T13:20:32.823424Z",
   "createdBy": {
    "id": 5,
    "siteId": 1,
    "userId": 3,
    "profileName": "Gandalf",
    "visible": true,
    "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/5"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "flags": {
    "sticky": false,
    "open": true,
    "deleted": false,
    "moderated": false,
    "visible": false,
    "unread": false,
    "watched": false
   },
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/microcosms/1"
    },
    {
     "rel": "site",
     "href": "/api/v1/sites/1"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

PUT

Updates a microcosm. The structure of the JSON to perform the update is:

{
  "title": "Rivendell",
  "description": "Refuge of the Elves, also known as Imladris. The House of Elrond is within Rivendell.",
  "meta": {"editReason": "Updated the description"}
}

Where:

Property Type Optional? Description
visibility String Required Must be one of 'public', 'protected' or 'private'. Where; 'public' allows the Microco.sm to be accessed without limitation and be discoverable across other sites, 'protected' allows the Microco.sm to be found and displayed publicly within the context of the current site, and 'private' means that the Microco.sm if fully private and won't be discoverable by guests.
title String Required A short textual name for the Microco.sm, displayed everywhere the Microco.sm is mentioned. Should be as terse, yet descriptive as possible.
description String Required A single line of text that provides information on the Microco.sm and provides the definition of what content is on-topic within the Micrcosm.
editReason String Required A single line of text that provides information on the reason for the update, this usually encapsulates a description of the change made.

Example request:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"title": "Rivendell","description": "Refuge of the Elves, also known as Imladris. The House of Elrond is within Rivendell.","meta":{"editReason": "Updated the description"}}' \
  https://dev1.microco.sm/api/v1/microcosms/1

Example response:

HTTP/1.1 302 Found
Date: Thu, 21 Nov 2013 15:16:52 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/microcosms/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly updated microcosm.

PATCH

PATCH allows partial updates to a resource. This is best used when some fragments of metadata require different or complex permissions. An example of this may be that the owner of a microcosm or a super user (site admin) can delete a microcosm, but only a super user can undelete a microcosm.

The body of a PATCH request is implemented according to RFC 6902, though it should be noted that the Content-Type remains application/json.

Our PATCH support is limited, but does provide an easy way to change small bits of meta data safely and without requiring you to construct a full PUT request. We support the use of the "op":"replace" for the JSON paths /meta/flags/sticky, /meta/flags/deleted, /meta/flags/moderated, and /meta/flags/open.

The JSON that you must send along with the PATCH request must be an array of PATCH instructions, like this:

[
  {"op":"replace", "path":"/meta/flags/sticky", "value": true},
  {"op":"replace", "path":"/meta/flags/open", "value": true},
  {"op":"replace", "path":"/meta/flags/moderated", "value": false},
  {"op":"replace", "path":"/meta/flags/deleted", "value": false},
]

The minimum number of acceptable PATCH instructions in the array is 1, a single replace instruction.

Example request:

curl -i \
  -X PATCH \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"op":"replace", "path":"/meta/flags/sticky", "value": true}]' \
  https://dev1.microco.sm/api/v1/microcosms/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 15:18:35 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

That request will set the sticky property of a microcosm to true. You will need to perform a GET on the updated resource to see the change reflected.

Microcosm fragment before:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
      ...
      "flags": {
       "sticky": false,
       "open": true,
       "deleted": false,
       "moderated": false,
       "visible": true,
       "unread": false,
       "watched": false
      },
      ...
    }
  },
  "error":null
}

Microcosm fragment after:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
      ...
      "edited": "2013-11-21T15:18:35.040362Z",
      "editedBy": {
        "id": 1,
        "siteId": 1,
        "userId": 1,
        "profileName": "Frodo",
        "visible": true,
        "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
        "meta": {
          "links": [
          ...
          ]
        }
      },
      "editReason": "Set sticky to true",
      "flags": {
        "sticky": true,
        "open": true,
        "deleted": false,
        "moderated": false,
        "visible": true,
        "unread": false,
        "watched": false
      },
      ...
    }
  },
  "error":null
}

The modified resource now reflects "sticky": true and the edited properties are populated describing the change to the resource.

DELETE

Deletes a microcosm.

Example request:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/microcosms/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 15:22:49 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

/conversations

Provides an interface to the conversations that exist on a site and the comments contained within them. A conversation is merely a titled (topical) collection of comments.

URLs and Methods

URL Pattern Method Description
/api/v1/conversations OPTIONS The Allow: header lists the methods available.
/api/v1/conversations POST Creates a new conversation on the current site.
/api/v1/conversations GET Returns information about the conversations that exist on the current site.
/api/v1/conversations/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/conversations/{id:[0-9]+} GET Returns information about the conversation specified by the numeric identifier and a collection of comments related to this conversation.
/api/v1/conversations/{id:[0-9]+} PUT Updates the conversation specified by the numeric identifier.
/api/v1/conversations/{id:[0-9]+} PATCH Updates specific fragments of a conversation resource specified by the numeric identifier.
/api/v1/conversations/{id:[0-9]+} DELETE Deletes the conversation specified by the numeric identifier.
/api/v1/conversations/{id:[0-9]+}/lastcomment OPTIONS The Allow: header lists the methods available.
/api/v1/conversations/{id:[0-9]+}/lastcomment GET Returns a redirect with a location linking to the last comment in the conversation.
/api/v1/conversations/{id:[0-9]+}/newcomment OPTIONS The Allow: header lists the methods available.
/api/v1/conversations/{id:[0-9]+}/newcomment Get Returns a redirect with a location linking to the first new comment in the conversation, or if there are no new comments then the last comment in the conversation.
/api/v1/conversations/{id:[0-9]+}/markread OPTIONS The Allow: header lists the methods available.
/api/v1/conversations/{id:[0-9]+}/markread PUT Marks the conversation as read.

The conversationId is based on a sequential number (that spans all sites in the microcosm network). You should not make any assumptions in your code that on a given site the identifiers will be contiguous (that the existence of id=17 infers the existence of id=16, id=15, etc on the given site).

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/conversations

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 15:53:05 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET,HEAD,POST

POST

Request:

The flow for creating a conversation is to create the conversation item, and then to create comments against the conversation. A conversation is simply an empty container for a list of comments.

The structure of the JSON to create a conversation is:

{
  "microcosmId": 1,
  "title": "There are whisperings that the Nazgûl are abroad"
}

Where:

Property Type Optional? Description
microcosmId Integer Required Identifies which Microco.sm this conversation will reside in. This property is required as every conversation must reside in a single Microco.sm.
title String Required A short textual description of the conversation that usually encapsulates the topic of the conversation. Should be as terse, yet descriptive as possible.

Example request:

curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"microcosmId": 1, "title": "There are whisperings that the Nazgûl are abroad"}' \
  https://dev1.microco.sm/api/v1/conversations

Example response:

HTTP/1.1 302 Found
Date: Thu, 21 Nov 2013 16:10:01 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/conversations/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly created conversation.

GET

Fetches a collection of conversations across all microcosms. If a valid access_token is provided then the collection may contain conversations that exist in microcosms not visible to guests.

Request:

The pagination query string parameters allow you to paginate the collection of conversations returned:

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/conversations

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:10:53 GMT
Content-Type: application/json
Content-Length: 1770
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "conversations": {
   "total": 1,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/conversations"
    }
   ],
   "type": "/api/v1/conversations",
   "items": [
    {
     "id": 1,
     "microcosmId": 1,
     "title": "There are whisperings that the Nazgûl are abroad",
     "meta": {
      "created": "2013-11-21T16:10:01.851585Z",
      "createdBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/1"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "flags": {
       "sticky": false,
       "open": true,
       "deleted": false,
       "moderated": false,
       "visible": true,
       "unread": false,
       "watched": false
      },
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/conversations/1"
       },
       {
        "rel": "microcosm",
        "href": "/api/v1/microcosms/1",
        "title": "Rivendell"
       }
      ]
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/conversations"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/conversations/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:14:44 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET,HEAD,PUT,PATCH,DELETE

GET

Fetches the detailed information about a single conversation, including a collection of comments contained within the conversation. The pagination query string parameters allow to you traverse the collection of comments.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/conversations/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:15:07 GMT
Content-Type: application/json
Content-Length: 1504
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "id": 1,
  "microcosmId": 1,
  "title": "There are whisperings that the Nazgûl are abroad",
  "comments": {
   "total": 0,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 0,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/conversations/1"
    }
   ],
   "type": "/api/v1/comments",
   "items": []
  },
  "meta": {
   "created": "2013-11-21T16:10:01.851585Z",
   "createdBy": {
    "id": 1,
    "siteId": 1,
    "userId": 1,
    "profileName": "Frodo",
    "visible": true,
    "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/1"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "flags": {
    "sticky": false,
    "open": true,
    "deleted": false,
    "moderated": false,
    "visible": true,
    "unread": false,
    "watched": false
   },
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/conversations/1"
    },
    {
     "rel": "microcosm",
     "href": "/api/v1/microcosms/1",
     "title": "Rivendell"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

PUT

Updates a conversation. The structure of the JSON to perform the update is:

{
  "microcosmId": 1,
  "title": "The Nazgûl have been sighted",
  "meta": {"editReason": "Updated the title"}
}

Where:

Property Type Optional? Description
microcosmId String Required Indicates which Microco.sm this conversation belongs to, you can move a conversation from one Microco.sm to another by changing this value. The move will work according to the user permissions against the destination Microco.sm, and the visibility scope of the destination Microco.sm. That is, you cannot move a conversation to a private Microco.sm for which you do not have rights.
title String Required A short textual name for the conversation, displayed everywhere the conversation is mentioned. Should be as terse, yet descriptive as possible.
editReason String Required A single line of text that provides information on the reason for the update, this usually encapsulates a description of the change made.

Example request:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"microcosmId": 1, "title": "The Nazgûl have been sighted", "meta": {"editReason": "Updated the title"}}' \
  https://dev1.microco.sm/api/v1/conversations/1

Example response:

HTTP/1.1 302 Found
Date: Thu, 21 Nov 2013 16:17:05 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/conversations/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly updated conversation.

PATCH

PATCH allows partial updates to a resource. This is best used when some fragments of metadata require different or complex permissions. An example of this may be that the owner (author) of a conversation or a super user (microcosm moderator or site admin) can delete a conversation, but only a super user can undelete a conversation.

The body of a PATCH request is implemented according to RFC 6902, though it should be noted that the Content-Type remains application/json.

Our PATCH support is limited, but does provide an easy way to change small bits of meta data safely and without requiring you to construct a full PUT request. We support the use of the "op":"replace" for the JSON paths /meta/flags/sticky, /meta/flags/deleted, /meta/flags/moderated, and /meta/flags/open.

The JSON that you must send along with the PATCH request must be an array of PATCH instructions, like this:

[
  {"op":"replace", "path":"/meta/flags/sticky", "value": true},
  {"op":"replace", "path":"/meta/flags/open", "value": true},
  {"op":"replace", "path":"/meta/flags/moderated", "value": false},
  {"op":"replace", "path":"/meta/flags/deleted", "value": false},
]

The minimum number of acceptable PATCH instructions in the array is 1, a single replace instruction.

Example request:

curl -i \
  -X PATCH \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"op":"replace", "path":"/meta/flags/sticky", "value": true}]' \
  https://dev1.microco.sm/api/v1/conversations/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:22:01 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

That request will set the sticky property of a conversation to true. You will need to perform a GET on the updated resource to see the change reflected.

Conversation fragment before:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
      ...
      "flags":{
        "sticky":false,
        "open":true,
        "deleted":false,
        "moderated":false,
        "visible":true,
      }
      ...
    }
  },
  "error":null
}

Conversation fragment after:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
      ...
      "edited": "2013-11-21T16:22:01.378813Z",
      "editedBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         ...
        ]
       }
      },
      "editReason": "Set sticky to true",
      "flags": {
      "sticky": true,
       "open": true,
       "deleted": false,
       "moderated": false,
       "visible": true,
       "unread": false,
       "watched": false
      },
      ...
    }
  },
  "error":null
}

The modified resource now reflects "sticky": true and the edited properties are populated describing the change to the resource.

DELETE

Deletes a conversation.

Example request:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/conversations/1

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:32:10 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

/events

Provides an interface to the events that exist on a site and the comments contained within them. An event describes some thing that happens some where at some time, and can be attended by some people. A collection of comments may be attached to an event.

URLs and Methods

URL Pattern Method Description
/api/v1/events OPTIONS The Allow: header lists the methods available.
/api/v1/events POST Creates a new event on the current site.
/api/v1/events GET Returns information about the events that exist on the current site.
/api/v1/events/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/events/{id:[0-9]+} GET Returns information about the event specified by the numeric identifier and a collection of comments related to this event.
/api/v1/events/{id:[0-9]+} PUT Updates the event specified by the numeric identifier.
/api/v1/events/{id:[0-9]+} PATCH Updates specific fragments of a event resource specified by the numeric identifier.
/api/v1/events/{id:[0-9]+} DELETE Deletes the event specified by the numeric identifier.
/api/v1/events/{id:[0-9]+}/lastcomment OPTIONS The Allow: header lists the methods available.
/api/v1/events/{id:[0-9]+}/lastcomment GET Returns a redirect with a location linking to the last comment in the event.
/api/v1/events/{id:[0-9]+}/newcomment OPTIONS The Allow: header lists the methods available.
/api/v1/events/{id:[0-9]+}/newcomment GET Returns a redirect with a location linking to the first new comment in the event, or if there are no new comments then the last comment in the event.

The eventId is based on a sequential number (that spans all sites in the microcosm network). You should not make any assumptions in your code that on a given site the identifiers will be contiguous (that the existence of id=17 infers the existence of id=16, id=15, etc).

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/events

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:55:22 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST,HEAD,GET

POST

Request:

The flow for creating an event is to create the event item, and then to create comments against the event. An event is simply an empty container for a list of comments, but with additional structure to describe the event and manage attendees. An event is something that occurs at a moment in time, at some place in space. It is perfectly fine to create an event without knowing the location for it and/or when it occurs.

The structure of the JSON to create an event is:

{
  "microcosmId": 1,
  "title": "Ale tasting",
  "when": "2013-11-22T20:00:00Z",
  "duration": 180,
  "where": "Green Dragon Inn",
  "lat": 51.674871,
  "lon": -0.216352,
  "north": 51.679581,
  "east": -0.208955,
  "south": 51.66984,
  "west": -0.227494,
  "rsvpLimit": 5
}

Where:

Property Type Optional? Description
microcosmId Integer Required Identifies which Microco.sm this event will reside in. This property is required as every event must reside in a single Microco.sm.
title String Required A short textual description of the event that usually encapsulates the topic of the event. Should be as terse, yet descriptive as possible.
when ISO8601 Datetime Optional The scheduled date for that the event occurs on.
duration Integer Optional How long the event runs for. The number is a time in minutes, so 180 = 3 hours. If no value is provided then we assume that an event has a duration of 60 minutes = 1 hour.
where String Optional A short textual description of the location of the event. This may be an address or just the title of the location. No geolocation will be done on this, it can be a useful label "Tower of London, UK" or a meaningless one "In the middle of a field".
lat Float Optional The latitude where a pin should be displayed on a map.
lon Float Optional The longitude where a pin should be displayed on a map.
north Float Optional A Northerly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
east Float Optional An Easterly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
south Float Optional A Southerly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
west Float Optional A Westerly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
rsvpLimit Integer Optional For events that are space constrained, this is the maximum number of people that can attend the event.

If you supply a time then we expect a duration. Likewise if you supply a location then we expect all of the location fields to be valid and logical (the pin outside of the bounding box isn't helpful to a user, etc).

Example request to create a proposed event:

curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"microcosmId": 1, "title": "Ale tasting?"}' \
  https://dev1.microco.sm/api/v1/events

Example request to create a confirmed/upcoming event:

curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"microcosmId": 1, "title": "Ale tasting", "when": "2013-11-22T20:00:00Z", "duration": 180, "where": "Green Dragon Inn", "lat": 51.674871, "lon": -0.216352, "north": 51.679581, "east": -0.208955, "south": 51.66984, "west": -0.227494, "rsvpLimit": 5}' \
  https://dev1.microco.sm/api/v1/events

Example response for both scenarios:

HTTP/1.1 302 Found
Date: Thu, 21 Nov 2013 17:35:14 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/events/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly created event.

GET

Fetches a collection of events across all Microcosms. If a valid access_token is provided then the collection may contain events that exist in private Microcosms not visible to guests.

Request:

The pagination query string parameters allow you to paginate the collection of events returned:

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/events

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 10:36:58 GMT
Content-Type: application/json
Content-Length: 1960
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "events": {
   "total": 1,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events"
    }
   ],
   "type": "/api/v1/events",
   "items": [
    {
     "id": 1,
     "microcosmId": 1,
     "title": "Ale tasting",
     "when": "2013-11-22T20:00:00Z",
     "duration": 180,
     "where": "Green Dragon Inn",
     "lat": 51.674871,
     "lon": -0.216352,
     "north": 51.679581,
     "east": -0.208955,
     "south": 51.66984,
     "west": -0.227494,
     "status": "upcoming",
     "meta": {
      "created": "2013-11-22T10:28:46.261132Z",
      "createdBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/1"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "flags": {
       "sticky": false,
       "open": true,
       "deleted": false,
       "moderated": false,
       "visible": true,
       "unread": false,
       "watched": false
      },
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/events/1"
       },
       {
        "rel": "microcosm",
        "href": "/api/v1/microcosms/1",
        "title": "Rivendell"
       }
      ]
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/events/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 10:40:42 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET,PUT,PATCH,DELETE

GET

Fetches the detailed information about a single event, including a collection of comments contained within the event. The pagination query string parameters allow to you traverse the collection of comments.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/events/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 10:41:03 GMT
Content-Type: application/json
Content-Length: 1722
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "id": 1,
  "microcosmId": 1,
  "title": "Ale tasting",
  "when": "2013-11-22T20:00:00Z",
  "duration": 180,
  "where": "Green Dragon Inn",
  "lat": 51.674871,
  "lon": -0.216352,
  "north": 51.679581,
  "east": -0.208955,
  "south": 51.66984,
  "west": -0.227494,
  "status": "upcoming",
  "rsvpLimit": 5,
  "rsvpSpaces": 5,
  "comments": {
   "total": 0,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 0,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events/1"
    }
   ],
   "type": "/api/v1/comments",
   "items": []
  },
  "meta": {
   "created": "2013-11-22T10:28:46.261132Z",
   "createdBy": {
    "id": 1,
    "siteId": 1,
    "userId": 1,
    "profileName": "Frodo",
    "visible": true,
    "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/1"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "flags": {
    "sticky": false,
    "open": true,
    "deleted": false,
    "moderated": false,
    "visible": true,
    "unread": false,
    "watched": false
   },
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events/1"
    },
    {
     "rel": "microcosm",
     "href": "/api/v1/microcosms/1",
     "title": "Rivendell"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

PUT

Updates an event. The structure of the JSON to perform the update is:

{
  "microcosmId": 1,
  "title": "Ale tasting",
  "when": "2013-11-22T20:00:00Z",
  "duration": 180,
  "where": "Green Dragon Inn",
  "lat": 51.674871,
  "lon": -0.216352,
  "north": 51.679581,
  "east": -0.208955,
  "south": 51.66984,
  "west": -0.227494,
  "rsvpLimit": 25,
  "meta": {
    "editReason": "Increased attendee number"
  }
}

Where:

Property Type Optional? Description
microcosmId Integer Required Identifies which Microco.sm this event will reside in. This property is required as every event must reside in a single Microco.sm.
title String Required A short textual description of the event that usually encapsulates the topic of the event. Should be as terse, yet descriptive as possible.
when ISO8601 Datetime Required The scheduled date for that the event occurs on.
duration Integer Required How long the event runs for. The number is a time in minutes, so 180 = 3 hours. If no value is provided then we assume that an event has a duration of 60 minutes = 1 hour.
where String Required A short textual description of the location of the event. This may be an address, and this value will be mapped based on the first result from a Google maps search of this value.
lat Float Optional The latitude where a pin should be displayed on a map.
lon Float Optional The longitude where a pin should be displayed on a map.
north Float Optional A Northerly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
east Float Optional An Easterly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
south Float Optional A Southerly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
west Float Optional A Westerly point that describes the limits of a bounding box, which in turn sets the zoom level of a map.
rsvpLimit Integer Required For events that are space constrained, this is the maximum number of people that can attend the event.
status String Required One of: 'proposed', 'upcoming', 'postponed' or 'cancelled'.
editReason String Required The reason the event is being updated.

Example request:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"microcosmId": 1, "title": "Ale tasting", "when": "2013-11-22T20:00:00Z", "duration": 180, "where": "Green Dragon Inn", "lat": 51.674871, "lon": -0.216352, "north": 51.679581, "east": -0.208955, "south": 51.66984, "west": -0.227494, "rsvpLimit": 25, "meta": {"editReason": "Increased attendee number"}}' \
  https://dev1.microco.sm/api/v1/events/1

Example response:

HTTP/1.1 302 Found
Date: Fri, 22 Nov 2013 10:43:28 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/events/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the updated event.

PATCH

PATCH allows partial updates to a resource. This is best used when some fragments of metadata require different or complex permissions. An example of this may be that the owner (author) of an event or a super user (microcosm moderator or site admin) can delete an event, but only a super user can undelete an event.

The body of a PATCH request is implemented according to RFC 6902, though it should be noted that the Content-Type remains application/json.

Our PATCH support is limited, but does provide an easy way to change small bits of meta data safely and without requiring you to construct a full PUT request. We support the use of the "op":"replace" for the JSON paths /meta/flags/sticky, /meta/flags/deleted, /meta/flags/moderated, and /meta/flags/open.

The JSON that you must send along with the PATCH request must be an array of PATCH instructions, like this:

[
  {"op":"replace", "path":"/meta/flags/sticky", "value": true},
  {"op":"replace", "path":"/meta/flags/open", "value": true},
  {"op":"replace", "path":"/meta/flags/moderated", "value": false},
  {"op":"replace", "path":"/meta/flags/deleted", "value": false},
]

The minimum number of acceptable PATCH instructions in the array is 1, a single replace instruction.

Example request:

curl -i \
  -X PATCH \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"op":"replace", "path":"/meta/flags/sticky", "value": true}]' \
  https://dev1.microco.sm/api/v1/events/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 10:45:52 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

That request will set the sticky property of an event to true. You will need to perform a GET of the updated resource to see the change.

Event fragment before:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
      ...
      "flags":{
        "sticky":false,
        "open":true,
        "deleted":false,
        "moderated":false,
        "visible":true,
        "isread": true
      }
      ...
    }
  },
  "error":null
}

Event fragment after:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
     ...
     "edited": "2013-11-22T10:45:52.3653Z",
     "editedBy": {
      "id": 1,
      "siteId": 1,
      "userId": 1,
      "profileName": "Frodo",
      "visible": true,
      "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
      "meta": {
       "links": [
       ...
       ]
      }
     },
     "editReason": "Set sticky to true",
     "flags": {
      "sticky": true,
      "open": true,
      "deleted": false,
      "moderated": false,
      "visible": true,
      "unread": false,
      "watched": false
     },
     ...
    }
  },
  "error":null
}

The modified resource now reflects "sticky": true and the edited properties are populated describing the change to the resource.

DELETE

Deletes an event.

Example request:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/events/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 10:47:40 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

/events/{id}/attendees

Provides an interface to describe who is attending which events, who has been invited and who has declined invitations.

URLs and Methods

URL Pattern Method Description
/api/v1/events/{id:[0-9]+}/attendees OPTIONS The Allow: header lists the methods available.
/api/v1/events/{id:[0-9]+}/attendees PUT Creates or updates a collection of attendees for the current event. Depending on the data sent, this is an invitation to an event, or a confirmation that someone will attend.
/api/v1/events/{id:[0-9]+}/attendees GET Returns information about the attendees for event.
/api/v1/events/{id:[0-9]+}/attendees/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/events/{id:[0-9]+}/attendees/{id:[0-9]+} GET Returns information about a specific attendee for an event. The information returned describes whether this is an invite, a maybe, a declined invite, or a confirmation of attendance.
/api/v1/events/{id:[0-9]+}/attendees/{id:[0-9]+} PUT Updates attendance resource. This is how you change the status to reflect attendance, or not, of the attendee.
/api/v1/events/{id:[0-9]+}/attendees/{id:[0-9]+} DELETE Deletes the attendance resource specified.

Whilst the eventId is based on a sequential number (that spans all sites in the microcosm network), the attendeeId is the profileId of the person attending the event. This means that if you have profile 27 and event 86574, and even if there are no other attendees, the URL would be /api/v1/events/86574/attendees/27.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/events/1/attendees

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:25:48 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST,HEAD,GET

PUT

Request:

The flow for creating an attendee is to create the event item, and then to create attendees against the event.

The structure of the JSON to create an attendee is:

[{
  "attendeeId": 1,
  "rsvp": "yes",
}]

It's an array, feel free to provide many attendees at once.

Where:

Property Type Optional? Description
attendeeId Integer Required Identifies which profile is attending the event. The attendeeId is the profileId of the person attending the event. Users may not randomly invite others, only the event owner or a super user (admin or moderator) can invite people to an event, though anyone can state that they are attending.
rsvpd String Optional Describes the RSVP state of the attendee, may be one of invited, yes (for attendance), maybe (for tentative) or no to decline the invite. If not supplied this defaults to "invited".

Example request to create an invitation for an attendee:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"attendeeId": 1}]' \
  https://dev1.microco.sm/api/v1/events/1/attendees

Example request to create a confirmation for the user whose authentication credentials token matches the attendeeId:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"attendeeId": 1, "rsvp": "yes"}]' \
  https://dev1.microco.sm/api/v1/events/1/attendees

Example response for both scenarios:

HTTP/1.1 302 Found
Date: Fri, 22 Nov 2013 11:29:19 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/events/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly created attendee resource.

GET

Fetches a collection of attendees for the current event.

Request:

The pagination query string parameters allow you to paginate the collection of events returned:

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/events/1/attendees

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:29:40 GMT
Content-Type: application/json
Content-Length: 2044
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "attendees": {
   "total": 1,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events/1/attendees"
    }
   ],
   "type": "/api/v1/events/0/attendees",
   "items": [
    {
     "attendeeId": 1,
     "attendee": {
      "id": 1,
      "siteId": 1,
      "userId": 1,
      "profileName": "Frodo",
      "visible": true,
      "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
      "meta": {
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/profiles/1"
        },
        {
         "rel": "site",
         "href": "/api/v1/sites/1"
        }
       ]
      }
     },
     "rsvp": "invited",
     "rsvpdOn": "2013-11-22T11:29:19.137938Z",
     "meta": {
      "created": "2013-11-22T11:29:19.137938Z",
      "createdBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/1"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/events/1/attendees/1"
       },
       {
        "rel": "profile",
        "href": "/api/v1/profiles/1"
       },
       {
        "rel": "event",
        "href": "/api/v1/events/1"
       }
      ]
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events/1/attendees"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/events/1/attendees/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:30:23 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET,PUT,DELETE

GET

Fetches the detailed information about a single attendee for an event.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/events/1/attendees/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:32:14 GMT
Content-Type: application/json
Content-Length: 1467
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "attendeeId": 1,
  "attendee": {
   "id": 1,
   "siteId": 1,
   "userId": 1,
   "profileName": "Frodo",
   "visible": true,
   "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
   "meta": {
    "links": [
     {
      "rel": "self",
      "href": "/api/v1/profiles/1"
     },
     {
      "rel": "site",
      "href": "/api/v1/sites/1"
     }
    ]
   }
  },
  "rsvp": "invited",
  "rsvpdOn": "2013-11-22T11:29:19.137938Z",
  "meta": {
   "created": "2013-11-22T11:29:19.137938Z",
   "createdBy": {
    "id": 1,
    "siteId": 1,
    "userId": 1,
    "profileName": "Frodo",
    "visible": true,
    "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/1"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/events/1/attendees/1"
    },
    {
     "rel": "profile",
     "href": "/api/v1/profiles/1"
    },
    {
     "rel": "event",
     "href": "/api/v1/events/1"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

PUT

Updates the attendee resource to reflect the new attendance state.

The structure of the JSON to perform the update is:

{
   "rsvp": "maybe"
}

Where the rsvp property is one of: invited, yes (for attendance), maybe (for tentative) or no to decline the invite.

Example request to set as attending:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"rsvp":"yes"}' \
  https://dev1.microco.sm/api/v1/events/1/attendees/1

Example request to set as not attending:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"rsvp":"no"}' \
  https://dev1.microco.sm/api/v1/events/1/attendees/1

Example request to set as maybe attending:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"rsvp":"maybe"}' \
  https://dev1.microco.sm/api/v1/events/1/attendees/1

Example response:

HTTP/1.1 302 Found
Date: Fri, 22 Nov 2013 11:33:17 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/events/1/attendees/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

DELETE

Deletes an attendee resource.

Example request:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/events/1/attendees/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:33:36 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

/comments

Provides an interface to comments. These are the bread and butter of a community web site, each comment is a piece of content attached to some other item (a conversation, an event, a poll, etc.) that discusses the item. Comments can be generally in response to the item, or specifically in response to another comment.

The format for the body of a comment is Markdown, with some minor additions to do things link recognising usernames when preceded with an @ or +, and embedding rich content about linked items where we are able to. There are also some restrictions on unsafe HTML such as the use of JavaScript and CSS.

General rule of thumb: Take text through a standard textbox or textarea and send it to us and we'll worry about formatting it.

URLs and Methods

URL Pattern Method Description
/api/v1/comments OPTIONS The Allow: header lists the methods available.
/api/v1/comments POST Creates a new comment on the current site.
/api/v1/comments/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/comments/{id:[0-9]+} GET Returns information about the comment specified by the numeric identifier and the HTML to show when rendering the comment. Also includes the parents and children for the comment to enable a threaded view.
/api/v1/comments/{id:[0-9]+} PUT Updates the comment specified by the numeric identifier.
/api/v1/comments/{id:[0-9]+} PATCH Updates specific fragments of a comment resource specified by the numeric identifier.
/api/v1/comments/{id:[0-9]+} DELETE Deletes the comment specified by the numeric identifier.
/api/v1/comments/{id:[0-9]+}/incontext OPTIONS The Allow: header lists the methods available.
/api/v1/comments/{id:[0-9]+}/incontext GET Returns a redirect to the API of the item that this comment belongs to, with the offset and limit set to ensure that the page on which this comment belongs is returned..

The commentId is based on a sequential number (that spans all sites in the microcosm network). You should not make any assumptions in your code that on a given site the identifiers will be contiguous (that the existence of id=17 infers the existence of id=16, id=15, etc).

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/comments

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 13:07:00 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST

POST

Request:

The flow for creating a comment is that you must already have some other item, and comments are attached to that. For this reason when you create a comment you also need to provide the itemType and itemId for the item that this comment will be attached to.

The structure of the JSON to create a comment is:

{
   "itemType": "conversation",
   "itemId": 1,
   "markdown": "Some text and a link to [vBulletin](http://www.vbulletin.com/)"
}

And if you were creating a comment that is a direct reply to another comment, then you should additionally provide the identifier of the comment you are replying to:

{
   "itemType": "conversation",
   "itemId": 1,
   "inReplyTo": 1,
   "markdown": "A rebuttal and a link Some text and a link to [Microcosm](http://microco.sm/)"
}

Where:

Property Type Optional? Description
itemType String Required Identifies the type of item that this comment is attached to. Must be one of: conversation, event, huddle or poll. E.g. If the comment was attached to /api/v1/conversations/1, then the itemType is conversation.
itemId Integer Required The identifier for the given type of item described by itemType. E.g. If the comment was attached to /api/v1/conversations/1, then the itemId is 1.
inReplyTo Integer Optional If the comment is an explicit response to an existing comment, then this is the identifier for that comment.
markdown String Required The textual content of the comment, markdown formatted. This will be converted automatically into HTML and any @mentions or links detected, HTML processed, etc. Note that all fields are scrubbed for bad input, and bad input is HTML or other formatting instructions that could affect the rendering of the content, or that makes a client vulnerable to cross-site scripting attacks.

Example request:

curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"itemType": "conversation","itemId": 1,"markdown": "I think we should get off the road"}' \
  https://dev1.microco.sm/api/v1/comments

And a reply to an existing comment:


curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"itemType": "conversation","itemId": 1,"inReplyTo": 1, "markdown": "Get off the road! **Quick!**"}' \
  https://dev1.microco.sm/api/v1/comments

Example response:

HTTP/1.1 302 Found
Date: Fri, 22 Nov 2013 13:27:27 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/comments/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly created comment.

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/comments/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 13:42:20 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET,HEAD,PUT,PATCH,DELETE

GET

Fetches the detailed information about a single comment. If this comment was inReplyTo another comment then it will also fetch the parents of this comment. Additionally if other comments are inReplyTo this comment then it will fetch up to a maximum of 5 replies.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/comments/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 13:44:00 GMT
Content-Type: application/json
Content-Length: 3617
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "id": 1,
  "itemType": "conversation",
  "itemId": 1,
  "revisions": 1,
  "inReplyTo": 0,
  "attachments": 0,
  "firstLine": "",
  "markdown": "I think we should get off the road",
  "html": "\u003cp\u003eI think we should get off the road\u003c/p\u003e\n",
  "meta": {
   "created": "2013-11-22T13:28:09.094412Z",
   "createdBy": {
    "id": 1,
    "siteId": 1,
    "userId": 1,
    "profileName": "Frodo",
    "visible": true,
    "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/1"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "edited": "2013-11-22T13:28:09.094412Z",
   "editedBy": {
    "id": 1,
    "siteId": 1,
    "userId": 1,
    "profileName": "Frodo",
    "visible": true,
    "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
    "meta": {
     "links": [
      {
       "rel": "self",
       "href": "/api/v1/profiles/1"
      },
      {
       "rel": "site",
       "href": "/api/v1/sites/1"
      }
     ]
    }
   },
   "parents": null,
   "children": [
    {
     "id": 2,
     "itemType": "conversation",
     "itemId": 1,
     "revisions": 1,
     "inReplyTo": 1,
     "markdown": "Get off the road! **Quick!**",
     "html": "\u003cp\u003eGet off the road! \u003cstrong\u003eQuick!\u003c/strong\u003e\u003c/p\u003e\n",
     "meta": {
      "created": "2013-11-22T13:28:09.704428Z",
      "createdBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/1"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "edited": "2013-11-22T13:28:09.704428Z",
      "editedBy": {
       "id": 1,
       "siteId": 1,
       "userId": 1,
       "profileName": "Frodo",
       "visible": true,
       "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
       "meta": {
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/1"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/1"
         }
        ]
       }
      },
      "flags": {
       "deleted": false,
       "moderated": false,
       "visible": false,
       "unread": false
      },
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/comments/2"
       },
       {
        "rel": "conversation",
        "href": "/api/v1/conversations/1"
       },
       {
        "rel": "up",
        "href": "/api/v1/conversations/1"
       }
      ]
     }
    }
   ],
   "flags": {
    "deleted": false,
    "moderated": false,
    "visible": false,
    "unread": false
   },
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/comments/1"
    },
    {
     "rel": "conversation",
     "href": "/api/v1/conversations/1"
    },
    {
     "rel": "up",
     "href": "/api/v1/conversations/1"
    },
    {
     "rel": "commentPage",
     "href": "/api/v1/conversations/1"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

PUT

Updates a comment. The structure of the JSON to perform the update is:

{
  "itemType": "conversation",
  "itemId": 1,
  "markdown": "The [ring](http://lotr.wikia.com/wiki/One_Ring) is taking me. If I put it on [he](http://lotr.wikia.com/wiki/Sauron) will find me."
}

You do not need to supply inReplyTo as it is immutable and it is not updated when you change the content of a comment nor the item that the comment is attached to. If you do supply it, it will be ignored.

Where:

Property Type Optional? Description
itemType String Required Identifies the type of item that this comment is attached to. Must be one of: conversation, event, huddle or poll. E.g. If the comment was attached to /api/v1/conversations/1, then the itemType is conversation.
itemId Integer Required The identifier for the given type of item described by itemType. E.g. If the comment was attached to /api/v1/conversations/1, then the itemId is 1.
markdown String Required The textual content of the comment, markdown formatted.

Example request:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"itemType": "conversation","itemId": 1,"markdown": "The [ring](http://lotr.wikia.com/wiki/One_Ring) is taking me. If I put it on [he](http://lotr.wikia.com/wiki/Sauron) will find me."}' \
  https://dev1.microco.sm/api/v1/comments/2

Example response:

HTTP/1.1 302 Found
Date: Fri, 22 Nov 2013 13:49:25 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/comments/2

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly updated comment.

PATCH

PATCH allows partial updates to a resource. This is best used when some fragments of metadata require different or complex permissions. An example of this may be that the owner (author) of a comment or a super user (microcosm moderator or site admin) can delete a comment, but only a super user can undelete a comment.

The body of a PATCH request is implemented according to RFC 6902, though it should be noted that the Content-Type remains application/json.

Our PATCH support is limited, but does provide an easy way to change small bits of meta data safely and without requiring you to construct a full PUT request. We support the use of the "op":"replace" for the JSON paths /meta/flags/deleted, and /meta/flags/moderated.

The JSON that you must send along with the PATCH request must be an array of PATCH instructions, like this:

[
  {"op":"replace", "path":"/meta/flags/moderated", "value": false},
  {"op":"replace", "path":"/meta/flags/deleted", "value": false},
]

The minimum number of acceptable PATCH instructions in the array is 1, a single replace instruction.

Example request:

curl -i \
  -X PATCH \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"op":"replace", "path":"/meta/flags/moderated", "value": true}]' \
  https://dev1.microco.sm/api/v1/comments/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 13:49:47 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

That request will set the moderated property of a comment to true. You will need to GET the comment to see the change reflected.

Comment fragment before:

{
  "context":"",
  "status":200,
  "data":{
    "id":1,
    ...
    "meta":{
      ...
      "flags":{
        "deleted":false,
        "moderated":false,
        "visible":true,
      }
      ...
    }
  },
  "error":null
}

Comment fragment after:

HTTP/1.1 404 Not Found
Date: Fri, 22 Nov 2013 13:50:33 GMT
Content-Type: application/json
Content-Length: 88
Connection: keep-alive

{
 "context": "",
 "status": 404,
 "data": null,
 "error": [
  "Comment not found"
 ]
}

As the modified comment now reflects "moderated": true the comment is not returned to an unauthenticated account or an account that does not have the right to view moderated comments.

DELETE

Deletes a comment.

Example request:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/comments/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 13:52:10 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

Single Resource In Context

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/comments/1/incontext

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 14:12:22 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET,HEAD

GET

For a given comment ID, will return a Location header that redirects to the API for the item that the comment is attached to, with the applicable limit and offset querystring to ensure that the comment is visible in the page of comments on the item.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/comments/1/incontext

Example response:

HTTP/1.1 307 Temporary Redirect
Date: Fri, 22 Nov 2013 14:14:18 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/conversations/1?comment_id=2

{
 "context": "",
 "status": 307,
 "data": null,
 "error": null
}

/profiles

Provides an interface to the set of profiles associated with the site.

URLs and Methods

URL Pattern Method Description
/api/v1/profiles OPTIONS The Allow: header lists the methods available.
/api/v1/profiles GET Returns summaries for the profiles associated with the site.
/api/v1/profiles/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/profiles/{id:[0-9]+} GET Returns the specified profile.
/api/v1/profiles/{id:[0-9]+} PUT Updates the specified profile.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/profiles

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 14:43:50 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST,HEAD,GET

GET

Fetches a collection of profiles for the given site.

Request:

The pagination query string parameters allow you to paginate the collection of events returned. There are two additional options: A boolean 'top' which will order the profiles by comment count (rather than the default alphanumerical ordering), and a string 'q' which filters the profiles returned by profile name.

Example request - usernames beginning with the letter 'u', ordered by comment count:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/profiles?q=u&top=true

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 14:44:07 GMT
Content-Type: application/json
Content-Length: 1091
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "profiles": {
   "total": 1,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/profiles"
    }
   ],
   "type": "/api/v1/profiles",
   "items": [
    {
     "id": 1,
     "siteId": 1,
     "userId": 1,
     "profileName": "Frodo",
     "visible": true,
     "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
     "meta": {
      "links": [
       {
        "rel": "self",
        "href": "/api/v1/profiles/1"
       },
       {
        "rel": "site",
        "href": "/api/v1/sites/1"
       }
      ]
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/profiles"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/profiles/1

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:01:09 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET,PUT,DELETE

GET

Fetches the specified profile.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/profiles/1

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:01:41 GMT
Content-Type: application/json
Content-Length: 853
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "id": 1,
  "siteId": 1,
  "userId": 1,
  "profileName": "Frodo",
  "visible": true,
  "styleId": 1,
  "itemCount": 0,
  "commentCount": 2,
  "created": "2013-11-25T12:13:05.841628Z",
  "lastActive": "2013-11-25T13:34:34.732561Z",
  "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
  "banned": false,
  "admin": true,
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/profiles/1"
    },
    {
     "rel": "site",
     "href": "/api/v1/sites/1"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

PUT

Updates a profile. The structure of the JSON to perform the update is:

{"profileName": "NewProfileName"}

Example request:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"microcosmId": 1, "profileName": "FrodoBaggins"}' \
  https://dev1.microco.sm/api/v1/profiles/1

Note that you do not need to supply the editedBy information as the only people that can update a profile are the owner of the profile and the owner of the site.

Example response:

HTTP/1.1 302 Found
Date: Mon, 25 Nov 2013 15:02:46 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/profiles/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly updated profile.

/updates

Provides an interface to the updates that a user has either explicitly subscribed to, or implicitly receives as a consequence of their actions (posting a new comment in a conversation) or the actions of other users (someone replying to a comment or quoting you). The updates contain the summary information of the thing that the update has occurred on, and also information about who triggered the update and the type of update.

To reduce noise levels, updates may be rolled up where applicable. This means that if there are 10 new comments in a conversation that you are watching, that you will only see one update relating to the most recent comment that has been posted. This service only rolls up some of the types of updates, mentions, and replies are never rolled up due to the personal connection and nature of that data.

URLs and Methods

URL Pattern Method Description
/api/v1/updates OPTIONS The Allow: header lists the methods available.
/api/v1/updates GET Returns information about the updates that exist on the current site.
/api/v1/updates/unread OPTIONS The Allow: header lists the methods available.
/api/v1/updates/unread GET Returns the number of new updates since the last time /updates was viewed. Note: Any visit to /updates will reset this count, even if you view page 1,000 of the updates.

The updateId is based on a sequential number (that spans all sites in the microcosm network). You should not make any assumptions in your code that on a given site the identifiers will be contiguous (that the existence of id=17 infers the existence of id=16, id=15, etc). The updateId is only provided to help developers refresh existing views without showing duplicates and cannot be used to access any other resource.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/updates

Example response:

HTTP/1.1 200 OK
Date: Thu, 21 Nov 2013 16:55:22 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET

GET

Fetches a collection of updates applicable to the authenticated user. If no valid access_token is provided then this will fail with a 401 unauthorised error. If the user is new to the site, then the update list will be empty.

Request:

The pagination query string parameters allow you to paginate the collection of updates returned:

Example request:

curl -i \
  -X GET \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/updates

Example response:

HTTP/1.1 200 OK
Date: Wed, 08 Jan 2014 14:27:23 GMT
Content-Type: application/json
Content-Length: 22406
Connection: keep-alive
Access-Control-Allow-Origin: *
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "updates": {
   "total": 5,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/updates"
    }
   ],
   "type": "/api/v1/updates",
   "items": [
    {
     "id": 23,
     "updateType": "new_comment",
     "itemType": "comment",
     "item": {
      "id": 10,
      "itemType": "conversation",
      "itemId": 1,
      "revisions": 1,
      "markdown": "Just need a post so that I can update the comment count",
      "html": "\u003cp\u003eJust need a post so that I can update the comment count\u003c/p\u003e\n",
      "meta": {
       "created": "2014-01-08T11:42:37.056354Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "edited": "2014-01-08T11:42:37.056354Z",
       "editedBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "deleted": false,
        "moderated": false,
        "visible": false,
        "unread": false
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/comments/10"
        },
        {
         "rel": "conversation",
         "href": "/api/v1/conversations/1",
         "title": "What type of leaf are you smoking?"
        },
        {
         "rel": "up",
         "href": "/api/v1/conversations/1"
        }
       ]
      }
     },
     "parentItemType": "conversation",
     "parentItem": {
      "id": 1,
      "microcosmId": 1,
      "title": "What type of leaf are you smoking?",
      "totalComments": 10,
      "totalViews": 34,
      "lastComment": {
       "id": 10,
       "created": "2014-01-08T11:42:37.056354Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       }
      },
      "meta": {
       "created": "2014-01-08T10:44:09.114149Z",
       "createdBy": {
        "id": 5,
        "siteId": 5,
        "userId": 1,
        "profileName": "Frodo",
        "visible": true,
        "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/5"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "sticky": false,
        "open": true,
        "deleted": false,
        "moderated": false,
        "visible": true
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "microcosm",
         "href": "/api/v1/microcosms/1",
         "title": "The Shire"
        }
       ]
      }
     },
     "meta": {
      "created": "2014-01-08T11:42:37.743665Z",
      "createdBy": {
       "id": 6,
       "siteId": 5,
       "userId": 3,
       "profileName": "Gandalf",
       "visible": true,
       "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
       "meta": {
        "flags": {},
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/6"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/5"
         }
        ]
       }
      }
     }
    },
    {
     "id": 18,
     "updateType": "reply_to_comment",
     "itemType": "comment",
     "item": {
      "id": 8,
      "itemType": "conversation",
      "itemId": 1,
      "revisions": 1,
      "inReplyTo": 7,
      "markdown": "You really do love your pipe-weed my boy.",
      "html": "\u003cp\u003eYou really do love your pipe-weed my boy.\u003c/p\u003e\n",
      "meta": {
       "created": "2014-01-08T10:58:57.254604Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "edited": "2014-01-08T10:58:57.254604Z",
       "editedBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "deleted": false,
        "moderated": false,
        "visible": false,
        "unread": false
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/comments/8"
        },
        {
         "rel": "conversation",
         "href": "/api/v1/conversations/1",
         "title": "What type of leaf are you smoking?"
        },
        {
         "rel": "up",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "inReplyTo",
         "href": "/api/v1/comments/7"
        },
        {
         "rel": "inReplyToAuthor",
         "href": "/api/v1/profiles/5",
         "title": "Frodo"
        }
       ]
      }
     },
     "parentItemType": "conversation",
     "parentItem": {
      "id": 1,
      "microcosmId": 1,
      "title": "What type of leaf are you smoking?",
      "totalComments": 10,
      "totalViews": 34,
      "lastComment": {
       "id": 10,
       "created": "2014-01-08T11:42:37.056354Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       }
      },
      "meta": {
       "created": "2014-01-08T10:44:09.114149Z",
       "createdBy": {
        "id": 5,
        "siteId": 5,
        "userId": 1,
        "profileName": "Frodo",
        "visible": true,
        "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/5"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "sticky": false,
        "open": true,
        "deleted": false,
        "moderated": false,
        "visible": true
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "microcosm",
         "href": "/api/v1/microcosms/1",
         "title": "The Shire"
        }
       ]
      }
     },
     "meta": {
      "created": "2014-01-08T10:58:57.842597Z",
      "createdBy": {
       "id": 6,
       "siteId": 5,
       "userId": 3,
       "profileName": "Gandalf",
       "visible": true,
       "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
       "meta": {
        "flags": {},
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/6"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/5"
         }
        ]
       }
      }
     }
    },
    {
     "id": 10,
     "updateType": "reply_to_comment",
     "itemType": "comment",
     "item": {
      "id": 5,
      "itemType": "conversation",
      "itemId": 1,
      "revisions": 1,
      "inReplyTo": 3,
      "markdown": "It chills me out too much.",
      "html": "\u003cp\u003eIt chills me out too much.\u003c/p\u003e\n",
      "meta": {
       "created": "2014-01-08T10:53:52.915307Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "edited": "2014-01-08T10:53:52.915307Z",
       "editedBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "deleted": false,
        "moderated": false,
        "visible": false,
        "unread": false
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/comments/5"
        },
        {
         "rel": "conversation",
         "href": "/api/v1/conversations/1",
         "title": "What type of leaf are you smoking?"
        },
        {
         "rel": "up",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "inReplyTo",
         "href": "/api/v1/comments/3"
        },
        {
         "rel": "inReplyToAuthor",
         "href": "/api/v1/profiles/5",
         "title": "Frodo"
        }
       ]
      }
     },
     "parentItemType": "conversation",
     "parentItem": {
      "id": 1,
      "microcosmId": 1,
      "title": "What type of leaf are you smoking?",
      "totalComments": 10,
      "totalViews": 34,
      "lastComment": {
       "id": 10,
       "created": "2014-01-08T11:42:37.056354Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       }
      },
      "meta": {
       "created": "2014-01-08T10:44:09.114149Z",
       "createdBy": {
        "id": 5,
        "siteId": 5,
        "userId": 1,
        "profileName": "Frodo",
        "visible": true,
        "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/5"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "sticky": false,
        "open": true,
        "deleted": false,
        "moderated": false,
        "visible": true
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "microcosm",
         "href": "/api/v1/microcosms/1",
         "title": "The Shire"
        }
       ]
      }
     },
     "meta": {
      "created": "2014-01-08T10:53:53.55172Z",
      "createdBy": {
       "id": 6,
       "siteId": 5,
       "userId": 3,
       "profileName": "Gandalf",
       "visible": true,
       "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
       "meta": {
        "flags": {},
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/6"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/5"
         }
        ]
       }
      }
     }
    },
    {
     "id": 7,
     "updateType": "reply_to_comment",
     "itemType": "comment",
     "item": {
      "id": 4,
      "itemType": "conversation",
      "itemId": 1,
      "revisions": 1,
      "inReplyTo": 3,
      "markdown": "Yes, but it's not as nice as Southlinch which is grown on the far side of Bree",
      "html": "\u003cp\u003eYes, but it\u0026#39;s not as nice as Southlinch which is grown on the far side of Bree\u003c/p\u003e\n",
      "meta": {
       "created": "2014-01-08T10:48:27.56858Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "edited": "2014-01-08T10:48:27.56858Z",
       "editedBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "deleted": false,
        "moderated": false,
        "visible": false,
        "unread": false
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/comments/4"
        },
        {
         "rel": "conversation",
         "href": "/api/v1/conversations/1",
         "title": "What type of leaf are you smoking?"
        },
        {
         "rel": "up",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "inReplyTo",
         "href": "/api/v1/comments/3"
        },
        {
         "rel": "inReplyToAuthor",
         "href": "/api/v1/profiles/5",
         "title": "Frodo"
        }
       ]
      }
     },
     "parentItemType": "conversation",
     "parentItem": {
      "id": 1,
      "microcosmId": 1,
      "title": "What type of leaf are you smoking?",
      "totalComments": 10,
      "totalViews": 34,
      "lastComment": {
       "id": 10,
       "created": "2014-01-08T11:42:37.056354Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       }
      },
      "meta": {
       "created": "2014-01-08T10:44:09.114149Z",
       "createdBy": {
        "id": 5,
        "siteId": 5,
        "userId": 1,
        "profileName": "Frodo",
        "visible": true,
        "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/5"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "sticky": false,
        "open": true,
        "deleted": false,
        "moderated": false,
        "visible": true
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "microcosm",
         "href": "/api/v1/microcosms/1",
         "title": "The Shire"
        }
       ]
      }
     },
     "meta": {
      "created": "2014-01-08T10:48:28.145569Z",
      "createdBy": {
       "id": 6,
       "siteId": 5,
       "userId": 3,
       "profileName": "Gandalf",
       "visible": true,
       "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
       "meta": {
        "flags": {},
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/6"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/5"
         }
        ]
       }
      }
     }
    },
    {
     "id": 2,
     "updateType": "reply_to_comment",
     "itemType": "comment",
     "item": {
      "id": 2,
      "itemType": "conversation",
      "itemId": 1,
      "revisions": 1,
      "inReplyTo": 1,
      "markdown": "Right now, Longbottom leaf is my favourite.",
      "html": "\u003cp\u003eRight now, Longbottom leaf is my favourite.\u003c/p\u003e\n",
      "meta": {
       "created": "2014-01-08T10:46:51.650047Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "edited": "2014-01-08T10:46:51.650047Z",
       "editedBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "deleted": false,
        "moderated": false,
        "visible": false,
        "unread": false
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/comments/2"
        },
        {
         "rel": "conversation",
         "href": "/api/v1/conversations/1",
         "title": "What type of leaf are you smoking?"
        },
        {
         "rel": "up",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "inReplyTo",
         "href": "/api/v1/comments/1"
        },
        {
         "rel": "inReplyToAuthor",
         "href": "/api/v1/profiles/5",
         "title": "Frodo"
        }
       ]
      }
     },
     "parentItemType": "conversation",
     "parentItem": {
      "id": 1,
      "microcosmId": 1,
      "title": "What type of leaf are you smoking?",
      "totalComments": 10,
      "totalViews": 34,
      "lastComment": {
       "id": 10,
       "created": "2014-01-08T11:42:37.056354Z",
       "createdBy": {
        "id": 6,
        "siteId": 5,
        "userId": 3,
        "profileName": "Gandalf",
        "visible": true,
        "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/6"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       }
      },
      "meta": {
       "created": "2014-01-08T10:44:09.114149Z",
       "createdBy": {
        "id": 5,
        "siteId": 5,
        "userId": 1,
        "profileName": "Frodo",
        "visible": true,
        "avatar": "/api/v1/files/66cca61feb8001cb71a9fb7062ff94c9d2543340",
        "meta": {
         "flags": {},
         "links": [
          {
           "rel": "self",
           "href": "/api/v1/profiles/5"
          },
          {
           "rel": "site",
           "href": "/api/v1/sites/5"
          }
         ]
        }
       },
       "flags": {
        "sticky": false,
        "open": true,
        "deleted": false,
        "moderated": false,
        "visible": true
       },
       "links": [
        {
         "rel": "self",
         "href": "/api/v1/conversations/1"
        },
        {
         "rel": "microcosm",
         "href": "/api/v1/microcosms/1",
         "title": "The Shire"
        }
       ]
      }
     },
     "meta": {
      "created": "2014-01-08T10:46:52.326072Z",
      "createdBy": {
       "id": 6,
       "siteId": 5,
       "userId": 3,
       "profileName": "Gandalf",
       "visible": true,
       "avatar": "/api/v1/files/122cf255cb3a5360355ac6cf6bb3f1107db3892a",
       "meta": {
        "flags": {},
        "links": [
         {
          "rel": "self",
          "href": "/api/v1/profiles/6"
         },
         {
          "rel": "site",
          "href": "/api/v1/sites/5"
         }
        ]
       }
      }
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/updates"
    }
   ]
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/updates/unread

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 10:40:42 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET

GET

Fetches a count of the number of updates that have been created since the last time /updates was visited. You can use this to show an indication to the user as to whether there are any new updates for them.

Example request:

curl -i \
  -X GET \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/updates/unread

Example response:

HTTP/1.1 200 OK
Date: Wed, 08 Jan 2014 14:30:01 GMT
Content-Type: application/json
Content-Length: 63
Connection: keep-alive
Access-Control-Allow-Origin: *
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": 5,
 "error": null
}

/updates/preferences

Provides an interface to see the type of updates that the user can receive and managing the default notification settings for these update types.

URLs and Methods

URL Pattern Method Description
/api/v1/updates/preferences OPTIONS The Allow: header lists the methods available.
/api/v1/updates/preferences GET Returns information about the preferences for all update types.
/api/v1/updates/preferences/{id:[0-9]+} OPTIONS The Allow: header lists the methods available.
/api/v1/updates/preferences/{id:[0-9]+} GET Returns information about a specific preference for an update type. This includes the email and SMS preferences for the given user for this update type.
/api/v1/updates/preferences/{id:[0-9]+} PUT Updates the preference for an update type. This is how you change the email notification options for a given type of update.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/updates/preferences

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:25:48 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET

GET

Fetches a collection of preferences for all of the update types.

Request:

The pagination query string parameters allow you to paginate the collection of updates returned:

Example request:

curl -i \
  -X GET \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/updates/preferences

Example response:

HTTP/1.1 200 OK
Date: Wed, 08 Jan 2014 14:45:05 GMT
Content-Type: application/json
Content-Length: 1383
Connection: keep-alive
Access-Control-Allow-Origin: *
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": [
  {
   "profileId": 5,
   "id": 1,
   "description": "When a comment has been posted in an item you are watching",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 2,
   "description": "When a comment of yours is replied to",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 3,
   "description": "When you are @mentioned in a comment",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 4,
   "description": "When you receive a new huddle comment",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 5,
   "description": "When an attendee added to an event you are watching",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 6,
   "description": "When a vote is cast in a poll you are watching",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 7,
   "description": "When an event you are attending is imminent",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  },
  {
   "profileId": 5,
   "id": 8,
   "description": "When a new item is created in a microcosm you are watching",
   "sendEmail": true,
   "sendSMS": false,
   "meta": {}
  }
 ],
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/updates/preferences/1

Example response:

HTTP/1.1 200 OK
Date: Fri, 22 Nov 2013 11:30:23 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET,PUT

GET

Fetches the detailed information about an update type.

Example request:

curl -i \
  -X GET \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/updates/preferences/1

Example response:

HTTP/1.1 200 OK
Date: Wed, 08 Jan 2014 14:46:26 GMT
Content-Type: application/json
Content-Length: 228
Connection: keep-alive
Access-Control-Allow-Origin: *
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "profileId": 5,
  "id": 1,
  "description": "When a comment has been posted in an item you are watching",
  "sendEmail": true,
  "sendSMS": false,
  "meta": {}
 },
 "error": null
}

PUT

Updates the update type prefers to reflect the new communication options.

The structure of the JSON to perform the update is:

{
   "rsvp": "maybe"
}

Where the rsvp property is one of: invited, yes (for attendance), maybe (for tentative) or no to decline the invite.

Example request to set it such that no notifications are sent:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"sendEmail": false, "sendSMS": false}' \
  https://dev1.microco.sm/api/v1/updates/preferences/1

Example response:

HTTP/1.1 302 Found
Date: Fri, 22 Nov 2013 11:33:17 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/updates/1/preferences/1

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Update preferences are the default preferences for any new watchers created for items that can issue these types of updates.

/whoami

A convenience resource that will acts like the *nix whoami command by determining your identity from the authentication token and issuing a redirect to the /api/v1/profiles of the currently authenticated user.

URLs and Methods

URL Pattern Method Description
/api/v1/whoami OPTIONS The Allow: header lists the methods available.
/api/v1/whoami GET Given a valid authentication token, will redirect to the applicable /api/v1/profiles for the authenticated user profiles.

Single

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/whoami

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:09:34 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET

GET

If you call this without an access_token you should expect to deal with a HTTP 401 Unauthorized error.

Example request:

curl -i \
  -H "Authorization: Bearer letmein" \
  -X GET \
  https://dev1.microco.sm/api/v1/whoami

Example response:

HTTP/1.1 307 Temporary Redirect
Date: Mon, 25 Nov 2013 15:12:04 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/profiles/1

{
 "context": "",
 "status": 307,
 "data": null,
 "error": null
}

Visit the destination in the Location header to view your profile.

/{type}/{id}/attributes

Provides the ability to store arbritrary key:value pairs of data against the most common entities. For example, you could store "Location = London, UK" against a profile or "Type = Festival" against an event.

Attributes can be stored against any of these high-level types: Site, Microcosms, Conversations, Events, Polls, Comments and Profiles. You can store numbers, booleans, strings and dates that are in YYYY-MM-DD format (and provided as a string).

Attributes defined by the owner of an item are not secret and have no special permissions. If a user has access to an entity, then the user can read all of the properties of that entity. Likewise, if a user has the ability to update the entity, then the user can modify all of the existing attributes as well as add new ones.

URLs and Methods

URL Pattern Method Description
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes OPTIONS The Allow: header lists the methods available.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes PUT Creates or updates a collection of one or more attributes for the current entity.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes GET Returns a collection of attributes for the given entity.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes DELETE Deletes a collection of attributes for the given entity.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes/{key:[0-9a-zA-Z_-]+} OPTIONS The Allow: header lists the methods available.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes/{key:[0-9a-zA-Z_-]+} PUT Creates or updates an attribute for the given entity.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes/{key:[0-9a-zA-Z_-]+} GET Returns a specific attribute for the given entity.
/api/v1/{type:[a-z]+}/{id:[0-9]+}/attributes/{key:[0-9a-zA-Z_-]+} DELETE Deletes an attribute for the given entity.

The type is only ever one of: site|microcosms|conversations|events|polls|comments|profiles.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:22:56 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET,HEAD,POST,PUT,DELETE

PUT

Request:

The flow for creating or updating a collection of attributes is to either create a single attribute or to create a whole collection at once. This method allows you to create one or more attributes at the same time, and if any attributes exist with the same key, then those attributes are updated to reflect the new values.

The structure of the JSON to create an attendee is:

[
  {
    "key": "MyString",
    "value": "an example string",
  },
  {
    "key": "MyDate",
    "value": "2007-01-27",
  },
  {
    "key": "MyBoolean",
    "value": true,
  },
  {
    "key": "MyInt",
    "value": 42,
  },
  {
    "key": "MyFloat",
    "value": 3.14159265359,
  }
]

Where:

Property Type Optional? Description
key String Required Identifies the attribute. Needs to conform to the regular expression [0-9a-zA-Z_-]+ as keys surface in URLs later.
value String|Number|Boolean Required The value to store. Any JSON string, number or boolean value is acceptable. All values are displayed to end users, so you should not be tempted to store JSON objects in here as strings or other such data that the average person wouldn't be expected to see.

Example request to create a collection of attributes:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"key": "MyString","value": "an example string"},{"key": "MyDate","value": "2007-01-27"},{"key": "MyBoolean","value": true},{"key": "MyInt","value": 42},{"key": "MyFloat","value": 3.14159265359}]' \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:24:12 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

The response is effectively just a 200 OK, no redirect happens in this scenario.

GET

Fetches a collection of attributes for the given entity.

Request:

The pagination query string parameters allow you to paginate the collection of events returned:

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:24:36 GMT
Content-Type: application/json
Content-Length: 651
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": {
  "attributes": {
   "total": 5,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/microcosms/1/attributes"
    }
   ],
   "type": "/api/v1/microcosms/0/attributes",
   "items": [
    {
     "key": "MyBoolean",
     "value": true
    },
    {
     "key": "MyDate",
     "value": "2007-01-27"
    },
    {
     "key": "MyFloat",
     "value": 3.141593
    },
    {
     "key": "MyInt",
     "value": 42
    },
    {
     "key": "MyString",
     "value": "an example string"
    }
   ]
  }
 },
 "error": null
}

DELETE

Request:

To delete attributes simply supply an array of the attributes to be deleted. You do not need to supply the value.

The structure of the JSON to delete one or more attributes is:

[
  {
    "key": "MyString",
  },
  {
    "key": "MyDate",
  },
  {
    "key": "MyBoolean",
  },
  {
    "key": "MyInt",
  },
  {
    "key": "MyFloat",
  }
]

Where:

Property Type Optional? Description
key String Required Identifies the attribute. Needs to conform to the regular expression [0-9a-zA-Z_-]+.

Example request to delete one or more attributes:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '[{"key": "MyString"},{"key": "MyDate"},{"key": "MyBoolean"},{"key": "MyInt"},{"key": "MyFloat"}]' \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:25:11 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

The response is effectively just a 200 OK, no redirect happens in this scenario.

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes/MyString

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:25:30 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET,HEAD,POST,PUT,DELETE

PUT

Request:

The flow for creating or updating a single attribute is to either create a single attribute or to create a whole collection at once. This method allows you to a single attribute at a time, and if an attributes exist with the same key, then that attribute is updated to reflect the new value. Only one attribute can exist for a given key.

The structure of the JSON to create an attribute is:

{
  "value": "an example string",
}

Where:

Property Type Optional? Description
value String|Number|Boolean Required The value to store. Any JSON string, number or boolean value is acceptable. All values are displayed to end users, so you should not be tempted to store JSON objects in here as strings or other such data that the average person wouldn't be expected to see.

The key is supplied via the URL, hence it is ignored if supplied in the JSON.

Example request to create an attribute:

curl -i \
  -X PUT \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"value": "an example string"}' \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes/MyString

Example response:

HTTP/1.1 302 Found
Date: Mon, 25 Nov 2013 15:26:29 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/microcosms/1/attributes/MyString

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

Your client should follow the Location header to retrieve detailed information about the newly created attribute.

GET

Fetches the detailed information about a single attendee for an attribute.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes/MyString

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:26:44 GMT
Content-Type: application/json
Content-Length: 118
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": {
  "key": "MyString",
  "value": "an example string"
 },
 "error": null
}

DELETE

Deletes an attribute.

Example request:

curl -i \
  -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/microcosms/1/attributes/MyString

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:26:57 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

/files

This is the endpoint for uploading user-generated files such as images. The endpoint accepts POSTDATA encoded as enctype/multipart-form and returns an array of file metadata records for each file that is uploaded. The file metadata stores information about when the file was uploaded, by whom, a SHA-1 hash of the file content, and the file mime-type.

Note that images (png/gif/jpeg) are currently the only accepted file type.

To retrieve a file, it must be accessed using the SHA-1 hash of the file content as the identifier. Files cannot be retrieved by their file metadata ID. Note that all files are accessible publicly via the SHA-1 identifier, so that links to files can be shared. However, the link itself will only be visible to users with the correct permission, giving the notion of "private URLs" to files.

URLs and Methods

URL Pattern Method Description
/api/v1/files OPTIONS The Allow: header lists the methods available.
/api/v1/files POST Given a valid authentication token, accepts files encoded as a multipart form.
/api/v1/files/{SHA-1:[0-9A-Za-z]+} GET Fetch a file by its SHA-1 hash of the file content.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/files

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:34:15 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST

POST

Example request:

curl -i \
  -H "Authorization: Bearer letmein" \
  -X POST \
  -F file=@red.jpg \
  -F file=@blue.jpg \
  https://dev1.microco.sm/api/v1/files

Example response:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:56:36 GMT
Content-Type: application/json
Content-Length: 465
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": [
  {
   "created": "2013-11-25T15:56:36.130607166Z",
   "fileSize": 1044,
   "fileHash": "6dfa7765c0426db8d27fda63fa9671794dd730a3",
   "mimeType": "image/jpeg",
   "width": 150,
   "height": 150
  },
  {
   "created": "2013-11-25T15:56:36.391334395Z",
   "fileSize": 2887,
   "fileHash": "f1f2f140aca0da4f49dce4fe5e92ffa3d5cfb19f",
   "mimeType": "image/jpeg",
   "width": 280,
   "height": 280
  }
 ],
 "error": null
}

Single Resource

OPTIONS

The URL for a created file is the SHA1 has of the file content. This is returned as fileHash when you create an image and is used to then refer to the image.

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/files/6dfa7765c0426db8d27fda63fa9671794dd730a3

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 15:59:06 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,GET

GET

The URL for a created file is the SHA1 has of the file content. This is returned as fileHash when you create an image and is used to then refer to the image.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/files/6dfa7765c0426db8d27fda63fa9671794dd730a3

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 16:01:50 GMT
Content-Type: image/jpeg
Content-Length: 1044
Connection: keep-alive

[binary image data that a browser would render or you could pass to a native image renderer]

/{type}/{id}/attachments

An attachment represents a link between an item and a file. To create an attachment, the file must already have been uploaded to /files and the item must also exist.

Attachments can be created on a comment or a profile (in which case it becomes the profile's avatar). Attachments are always accessed through the path of the parent object, e.g. /comments/1/attachments or /profiles/1/attachments.

Once created on a comment or profile, the attachments can be listed by fetching /{type}/{id}/attachments which returns a paginated list of attachments on the item, e.g. /profiles/1/attachments.

URLs and Methods

URL Pattern Method Description
/api/v1/files OPTIONS The Allow: header lists the methods available.
/api/v1/{type}/{id}/attachments POST Given a valid access token with write permissions on the item, allows creation of an attachment (i.e. an association between a file and an item).
/api/v1/{type}/{id}/attachments GET Given a valid access token, fetch the attachments for a given item.

Collection

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/comments/1/attachments

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 16:19:47 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,POST,HEAD,GET

POST

The URL for a created file is the SHA1 has of the file content. This is returned as fileHash when you create an image and is used to then refer to the image.

Example request:

curl -i \
  -X POST \
  -H "Authorization: Bearer letmein" \
  -H "Content-Type: application/json" \
  -d '{"FileHash":"6dfa7765c0426db8d27fda63fa9671794dd730a3"}' \
  https://dev1.microco.sm/api/v1/comments/1/attachments

Example response:

HTTP/1.1 302 Found
Date: Mon, 25 Nov 2013 16:21:28 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive
Location: /api/v1/comments/1/attachments

{
 "context": "",
 "status": 302,
 "data": null,
 "error": null
}

GET

Attachments are returned as a paginated list, with a related link that references the file directly and can be used to inline the image into HTML or a native control.

Example request:

curl -i \
  -X GET \
  https://dev1.microco.sm/api/v1/comments/1/attachments

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 16:22:40 GMT
Content-Type: application/json
Content-Length: 1069
Connection: keep-alive
Cache-Control: no-cache, max-age=0

{
 "context": "",
 "status": 200,
 "data": {
  "attachments": {
   "total": 1,
   "limit": 25,
   "offset": 0,
   "maxOffset": 0,
   "totalPages": 1,
   "page": 1,
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/comments/1/attachments"
    }
   ],
   "type": "attachments",
   "items": [
    {
     "profileId": 1,
     "fileHash": "6dfa7765c0426db8d27fda63fa9671794dd730a3",
     "created": "2013-11-25T16:21:28.134366Z",
     "meta": {
      "links": [
       {
        "rel": "related",
        "href": "/api/v1/files/6dfa7765c0426db8d27fda63fa9671794dd730a3",
        "title": "File resource"
       }
      ]
     }
    }
   ]
  },
  "meta": {
   "links": [
    {
     "rel": "self",
     "href": "/api/v1/comments/1/attachments"
    }
   ],
   "permissions": {
    "create": false,
    "read": true,
    "update": false,
    "delete": false,
    "closeOwn": false,
    "openOwn": false,
    "readOthers": false,
    "guest": true,
    "banned": false,
    "owner": false,
    "moderator": false,
    "siteOwner": false
   }
  }
 },
 "error": null
}

Single Resource

OPTIONS

Example request:

curl -i \
  -X OPTIONS \
  https://dev1.microco.sm/api/v1/comments/1/attachments/6dfa7765c0426db8d27fda63fa9671794dd730a3

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 16:31:27 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,DELETE

DELETE

To remove an attachment from comment or profile, issue a DELETE request using the fileHash as the identifier.

curl -X DELETE \
  -H "Authorization: Bearer letmein" \
  https://dev1.microco.sm/api/v1/comments/1/attachments/6dfa7765c0426db8d27fda63fa9671794dd730a3

Example response:

HTTP/1.1 200 OK
Date: Mon, 25 Nov 2013 16:32:14 GMT
Content-Type: application/json
Content-Length: 66
Connection: keep-alive

{
 "context": "",
 "status": 200,
 "data": null,
 "error": null
}

Currently attachments can't be deleted from profiles, so to replace an avatar upload the file and link it as an attachment to the appropriate profile. This will override the existing avatar. In future an avatar picker will allow users see previous avatars they have used and delete them if needed.

Back to top