Transports

The DeepAffex™ Cloud API endpoints are available on HTTP REST and WebSocket transports. The DeepAffex™ Cloud does not limit access across different transports, so you may use the transports interchangeably.

For both the REST and the WebSocket transports, API endpoints are transacted using data in the JSON format. For WebSocket, Protocol buffers were an old legacy method used to encode data.

For simplicity, we will refer to "HTTP-based access using RESTful patterns" as the REST API and the WebSocket equivalent as the WebSocket API.

The REST API is available at https://api.deepaffex.ai. The WebSocket API is available at: wss://api.deepaffex.ai.1

Please note that there are different routing options available, please refer to the chapter on regions and clusters to know more about them.

An important difference between the REST and WebSockets API is that the Measurements.Subscribe endpoint is only available on the WebSocket API. This endpoint is used to get real-time intermediate and final results of an active measurement over a bidirectional WebSocket connection.

WebSockets

This transport method is highly optimized and provides a fast and efficient method of communicating with DeepAffex™ Cloud. We recommend using the WebSocket API for platforms where real-time results are required.

Connection

During connection creation, the string "json" needs to be passed as the WebSocket protocol to the server which indicates to the server that the client's payloads will be JSON. To maintain a connection with the DeepAffex™ Cloud, you must implement proper ping/pong heartbeats as required by the WebSocket standard specification.

In addition to the standard use of WebSocket connectivity mechanics, the DeepAffex™ Cloud uses a custom request/response exchange pattern outlined below.

Request structure

A WebSocket request has to be a buffer, with the following structure:

Buffer( [ string:4 ][ string:10 ][ string/buffer:variablelength ] )

The first 4 bytes are an Action ID for the request, which is defined in the Endpoint Summary Table.

The next 10 bytes are a Request ID - a string identifier unique for each request. The client is responsible for creating a unique Request ID. It could be a counter or a randomly generated alphanumeric string e.g., "JDUEHDJEKO" or "000000001". This ID is only used within the current connection and does not interfere with other concurrent connections using the same token. Request IDs are not stored, so reusing them is possible however not recommended.

The remaining bytes represent the full body of your request in JSON format. In the legacy system, it used to be a serialized Protobuf. The DeepAffex™ Protobuf definitions are still available for download on the DeepAffex™ website.

Response structure

Requests that don't follow the structure defined above aren't processed. Instead, the following response is returned:

{
  Code: "INCORRECT_REQUEST"
}

Correctly structured requests get responses with the following structure:

Buffer( [ string:10 ][ string:3 ][ string/buffer:variablelength ] )

The first 10 bytes are the Request ID matching a request to a response.

The next 3 bytes are an HTTP status identifier. Status codes are defined in the Header Response Codes Table.

The remaining bytes are the response body in JSON format. In the legacy system, it used to be a serialized Protobuf which could be deserialized using the DeepAffex™ Protobuf definitions.

The client needs to manage requests in memory and await the response asynchronously. The DeepAffex™ Cloud will always respond to a request to close it out, regardless of if there is an error or not. In addition, to the status code, the body will also contain relevant error information.

Details

An important difference in the call methods is translating query string and parameters that would typically be sent via the REST service to the WebSocket API. As an example, shown below are properties when making a request to the Meta.retrieveByType endpoint:

  {
    "Foo": "bar",
    "Query": {
      "Namespace": "all",
      "Fields": "Foo,Bar"
    },
    "Params": {
      "Type": "Group",
      "ID": "7ab8bee7-808c-4123-9811-e385adb8c77d"
    }
  }

In essence Query and Params are values that are extracted from the payload body and interpreted as values that would typically be expected by a REST request.

Error messages are transported in turn in similar object formats as listed below. The WebSocket interface also follow this pattern.

Note: Many endpoints use arrays in the root of the payload. If you are still using our old legacy method of Protobufs, then unfortunately Protobufs do not support rooted arrays, hence the value needs to be wrapped in an object. The DeepAffex™ Cloud looks for the Values property in a payload and handles the containing array as a root array. The following is an example of a request to Groups.addUsers:

REST request example:

    [
        "7ab8bee7-808c-4123-9811-ef85adb8c77f",
        "7ab8bee7-808c-4123-9811-ef85adb8c75f",
        "7ab8bee7-808c-4123-9811-ef85adb8c71f",
        "7ab8bee7-808c-4123-9811-ef85adb8c72f",
        "7ab8bee7-808c-4123-9811-ef85adb8c77f"
    ]

Protobuf wrapped example of the same payload:

  {
    "Values": [
        "7ab8bee7-808c-4123-9811-ef85adb8c77f",
        "7ab8bee7-808c-4123-9811-ef85adb8c75f",
        "7ab8bee7-808c-4123-9811-ef85adb8c71f",
        "7ab8bee7-808c-4123-9811-ef85adb8c72f",
        "7ab8bee7-808c-4123-9811-ef85adb8c77f"
    ]
  }

First steps

Upon connecting to the DeepAffex™ Cloud, we recommend checking the current API version and general status. This is done by calling the General.Status endpoint which will respond with the appropriate status details. This endpoint does not require any authentication.

For most other endpoints though, an appropriate Authorization header must be supplied. This is discussed in the next section.

1

For compatibility reasons, you can also use ports 9443 and 9080 for REST and WebSocket respectively but for new applications please use the default port, 443.