Calling the APIs

If you are using the containerized version of mitter.io, you simply need to replace the host api.mitter.io with the host that you set, the default being localhost:11901. Refer the containerization docs for more information.

A quick note on SSL The API endpoint api.mitter.io is available with only HTTPS. You might currently face issues with our certificate provider - letsencrypt (and its co-signer IdentTrust), as neither of them are trusted roots in the JDK installations prior to Java 8u101 and this problem might exist in other programming environments also. To use SSL with mitter.io APIs, you can either manually add them to the JDK keystore or upgrade to JDK 8u101 and similarly for other environments. We will soon be moving to more widely-trusted SSL providers.

At the heart of using mitter.io is understanding the semantics and conventions of the APIs that are provided. mitter.io is an API-first product and all related distributables borrow from the same convention and are built with extending those same semantics to different abstractions.

The complete API documentation is available here

Basic Conventions

Mitter exposes a RESTful API leveraging the usage of HTTP verbs and status codes to whatever extent possible. All data is exposed and consumed only using JSON as a serialization format, with one deviation when it comes to binary data (discussed further). A Content-Type header is absolutely mandatory in every single request (except multi-part) and no other content-type is supported nor is support for the same planned.

All top-level entities are called Identifiables in mitter and CRUD operations require and return only the identifier of those entities.

Basic Response Conventions

Mitter does not return objects with success-indicator fields. A non 2XX or 3XX status code denotes an error and contains an object with the signature:

{
    "error": <a human readable error type>,
    "message": <a human readable error message>,
    "error_code": <a specific error code, that is enumerated along with each API>
}

All other APIs return objects of specific shape that is documented in the API documentation.

Basic Request Conventions

Mitter accepts POST/PUT requests with the request a JSON with the shape of the entity that the verb acts on. GET queries are speciailised using query parameters and PATCH requests have separate entity-diff objects. For instance, a PUT request for application properties is as follows:

PUT /applications/{appId}/property

{
    "systemName": "google-oauth-credential",
    "instanceName": "default-oauth",
    ...
}

However, the PATCH request is simply:

PATCH /applications/{appId}/property/{systemName}/{instanceName}

{
    "makeDefault": boolean
}

Identifiers

All top-level entities are recognized as Identifiable by Mitter and hence are always associated by a unique ID. Despite being globally unique IDs, they are still namespaced by the application they are a part of, in the sense that there is no supported querying model that allows retrieval or operations upon these entities without requiring the application id.

When an identifier is part of the entity, it is supplied as a string-value of a field in the entity. For instance:

User {
    "userId": <the users uuid>,
    "screenName": {
       ...
    }
}

However, when identifiers are supplied independently of their entities, they are nested in a single-field object like:

{
    "identifier": <the identifier>
}

Even if an identifier for an entity is nested within another entity, it is still represented using the single-field value as mentioned above. For instance, the shape of a message is:

Message {
    "messageId": "id-of-the-message-as-a-string",
    ...
    "senderId": {
        "identifier": "id-of-the-sender-as-a-string"
    }
}

In the above example, the identifier of the sender is encoded in a single-field object. Instead, if the entity sender itself was nested within message, the shape would look like:

Message {
    "messageId": "id-of-the-message-as-a-string",
    ...
    "sender": {
        "senderId": "id-of-the-sender-as-a-string"
        ...
    }

Note that this is not an actual object, but is simply used demonstratively.

NOTE Mitter will soon support the field identifier nested in all entity objects, such that a standalone identifier object will be a sub-object of the entity object. This will make it easy for clients to use object-merge and object-pick type operations.

Supplying Binary Data

Please refer to the "Sending binary payloads" section in the reference documentation for more information on how to send binary payloads.

Displaying Images

When sending a Message as described above, the returned value will contain, as one of its messageDatum elements, a key called link which contains a URI to the image. The URI has a placeholder $repr which is to be replaced by the representation type that was originally requested. For more information refer to the Image Messages section in the reference document.

representationType for images is one of the following:

  • base The image that was uploaded as-is.

  • standard The image, processed and resized for full-size display with reasonable dimensions.

  • thumbnail The image resized to be used as a thumbnail.

Mitter uploads all images to a CDN and the images are served from there. The endpoint above issues a 301 Moved Permanently to point to the CDN. However, there might be a brief interval when the image is not available on the CDN. During this time the endpoint will return a 200 OK with the image data which is stored in an intermediate temporary storage till the upload to S3 takes place.

NOTE The media hosted URL from the mitter server requires standard authentication, but the CDN URIs are public. This allows anyone to fetch images using the CDN URL if it is shared. We will soon be allowing developers to specify their own CDN endpoints (for instance, their own S3 buckets) on which they can set permissions as required.

Last updated