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:
Deviations from pure REST and HATEOAS:
application/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.
At the highest level you can imagine that the core flow through the API is this:
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.
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. |
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.
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. |
We support callbacks using JSONP. To achieve that 3 things are needed:
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.
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 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.
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
}
}
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. |
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 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.
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.
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.
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.
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. |
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
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
}
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.
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).
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
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.
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
}
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
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
}
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 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.
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
}
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.
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).
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
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.
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
}
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
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
}
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 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.
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
}
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.
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).
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
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.
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
}
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
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
}
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 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.
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
}
Provides an interface to describe who is attending which events, who has been invited and who has declined invitations.
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
.
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
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.
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
}
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
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
}
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
}
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
}
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.
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).
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
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.
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
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
}
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 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.
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
}
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
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
}
Provides an interface to the set of profiles associated with the site.
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. |
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
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
}
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
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
}
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.
A search interface to allow full-text queries to be performed against all things on the given site.
URL Pattern | Method | Description |
---|---|---|
/api/v1/search | OPTIONS | The Allow: header lists the methods available. |
/api/v1/search | GET | Performs a fulltext search for a given query, filtering the results according to search options. |
Example request:
curl -i \
-X OPTIONS \
https://dev1.microco.sm/api/v1/search
Example response:
HTTP/1.1 200 OK
Date: Wed, 04 Dec 2013 14:54:06 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: keep-alive
Allow: OPTIONS,HEAD,GET
A full-text search is performed by simply providing the search term(s) in the query string. The search can be further restricted by providing optional parameters, and a valid access token will return any non-public items that the given user has permission to see (conversations in a non-public microcosm, for example).
The following query string params are supported:
Querystring Key | Type | Default Value | Description |
---|---|---|---|
Key | Value | Default value if not supplied | Description |
q | string | null | The user submitted search terms. This is a required field. |
type | []string | null (search everything) | The capability to filter the search to only items of a given type.
type=conversations&type=events would filter the results to *only* conversations AND events. Valid values for type are comment , conversation , event , huddle , microcosm , poll , and profile . If you filter to a commentable type such as conversation then the query includes the comments of that conversation. |
inTitle | boolean | false | If true then the search will only be performed against the titles of entities. In the case of something like an event this means that only the event title is searched and not the event comments. |
authorId | integer | null | If greater than 0 then the search will be restricted to all items authored by this profile ID. If the profile ID does not exist on this site, then nothing is returned. |
Of the above, only q
is required. If any of the others are supplied, then they will be applied to the search in addition to the search terms within q
.
All of the query paramaters can also be supplied via the search parameter q
. To do so simply format them as key:value
and space separate them. So the query ?q=ale&inTitle=true&type=event
can also be represented as ale inTitle:true type:event
. This functionality enables omnibox style searching, and permalink searching (the ability to link to a complex search and for that search to be re-run).
Example request showing all params:
curl -i \
-H "Authorization: Bearer letmein" \
-X GET \
"https://dev1.microco.sm/api/v1/search?q=ale&inTitle=true&type=event&authorId=1"
Example response:
HTTP/1.1 200 OK
Date: Wed, 04 Dec 2013 15:20:40 GMT
Content-Type: application/json
Content-Length: 2103
Connection: keep-alive
Cache-Control: no-cache, max-age=0
{
"context": "",
"status": 200,
"data": {
"query": {
"q": "ale",
"type": [
"event"
],
"inTitle": true,
"authorId": 1,
"searched": "ale inTitle:true type:event authorId:1"
},
"timeTakenInMs": 62,
"results": {
"total": 1,
"limit": 25,
"offset": 0,
"maxOffset": 0,
"totalPages": 1,
"page": 1,
"links": [
{
"rel": "self",
"href": "/api/v1/search?authorId=1\u0026inTitle=true\u0026q=ale\u0026type=event"
}
],
"type": "result",
"items": [
{
"itemType": "event",
"item": {
"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,
"meta": {
"created": "2013-12-04T14:28:24.858836Z",
"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"
}
]
}
},
"rank": 0.12618599832057953,
"lastModified": "2013-12-04T15:16:51.029779Z",
"highlight": "\u003cb\u003eAle\u003c/b\u003e tasting"
}
]
}
},
"error": null
}
Example request showing just the q
param:
curl -i \
-H "Authorization: Bearer letmein" \
-X GET \
"https://dev1.microco.sm/api/v1/search?q=road"
Example response:
HTTP/1.1 200 OK
Date: Wed, 04 Dec 2013 15:32:45 GMT
Content-Type: application/json
Content-Length: 6571
Connection: keep-alive
Cache-Control: no-cache, max-age=0
{
"context": "",
"status": 200,
"data": {
"query": {
"q": "road",
"searched": "road"
},
"timeTakenInMs": 68,
"results": {
"total": 2,
"limit": 25,
"offset": 0,
"maxOffset": 0,
"totalPages": 1,
"page": 1,
"links": [
{
"rel": "self",
"href": "/api/v1/search?q=road"
}
],
"type": "result",
"items": [
{
"itemType": "comment",
"item": {
"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-12-04T14:28:30.235965Z",
"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-12-04T14:28:30.235965Z",
"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"
}
]
}
},
"parentItemType": "conversation",
"parentItem": {
"id": 1,
"microcosmId": 1,
"title": "There are whisperings that the Nazgûl are abroad",
"meta": {
"created": "2013-12-04T14:28:20.13916Z",
"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"
}
]
}
},
"rank": 0.05000000074505806,
"lastModified": "2013-12-04T14:28:30.273775Z",
"highlight": "Get off the \u003cb\u003eroad\u003c/b\u003e! **Quick!**"
},
{
"itemType": "comment",
"item": {
"id": 1,
"itemType": "conversation",
"itemId": 1,
"revisions": 1,
"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-12-04T14:28:29.389481Z",
"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-12-04T14:28:29.389481Z",
"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/1"
},
{
"rel": "conversation",
"href": "/api/v1/conversations/1"
},
{
"rel": "up",
"href": "/api/v1/conversations/1"
}
]
}
},
"parentItemType": "conversation",
"parentItem": {
"id": 1,
"microcosmId": 1,
"title": "There are whisperings that the Nazgûl are abroad",
"meta": {
"created": "2013-12-04T14:28:20.13916Z",
"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"
}
]
}
},
"rank": 0.05000000074505806,
"lastModified": "2013-12-04T14:28:29.407767Z",
"highlight": "I think we should get off the \u003cb\u003eroad\u003c/b\u003e"
}
]
}
},
"error": null
}
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.
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.
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
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
}
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
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
}
Provides an interface to see the type of updates that the user can receive and managing the default notification settings for these update types.
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. |
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
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
}
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
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
}
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.
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.
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. |
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
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.
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.
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
.
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
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.
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
}
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.
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
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.
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
}
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
}
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.
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. |
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
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
}
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
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]
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
.
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. |
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
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
}
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
}
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
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.