We intend this blog post for anyone interested in building an Orchestrate client (e.g. the Node.js client), interested in general REST API concepts, or who simply wants to better understand how Orchestrate works.

The Orchestrate service is powered by a HTTP REST API. The full documentation for the API is available here. In this blog post I want to outline some things to keep in mind when building a REST client for Orchestrate.

Data Format

The API follows the same patterns as many of today’s service APIs.

The content body of all HTTP store operations (PUT, POST… etc) are required to be valid Javascript Object Notation (JSON). The HTTP accept header is allowed to be application/json or */* (in which case JSON input is assumed).

Malformed JSON is rejected, for more detailed information on response codes and error codes see below.

All response data from Orchestrate comes back as JSON. For example, a Key-Value GET request will return a response like below where the JSON object returned is the object that was stored to that key.

curl -X GET https://api.orchestrate.io/v0/users/john --user "{apiKeyHere}:"
   "nickname": "Jonny",
   "firstname": "John",
   "lastname": "Smith"

Some of the Orchestrate API resources return nested JSON structures that give you back multiple results in one response. For examples, take a look at KV List, Graph GET, and Event List.

At this time, Orchestrate does not support XML, YAML or other response formats.


When an application is created in the Orchestrate Dashboard an API key is generated. API keys are used with HTTP Basic authentication to authenticate each request. These keys can be removed, new ones can be generated and there is no limit to the number of keys that can be created.

At the moment all keys have create, read, update and delete permissions. They are designed to be used as part of a server-side system that makes requests to our API.

The HTTP “Basic” authentication header (as defined by the HTTP specification) must be created by concatenation of a username string and a password string. These two strings must be separated by a “:” colon character. The resulting string is then Base64 encoded and prefixed with the string “Basic “.

In Java, this would like something like so (with the sun.misc.BASE64Encoder util class):

String username = "in Orchestrate this is where the API key goes";
String password = ""; // is left blank with Orchestrate
byte[] upBytes = (username + ":" + password).getBytes();
String b64enc = new BASE64Encoder().encode(upBytes);
String basicAuthHeaderValue = "Basic " + b64enc;

// -> Basic aW4gT3JjaGVzdHJhdGUgdGhpcyBpcyB3aGVyZSB0aGUgQVBJIGtleSBnb2VzOg==

To authenticate with Orchestrate, an API key needs to be used in place of the “username” field in the credentials used to build the HTTP Basic Auth header.

Most HTTP client libraries come with support for building this HTTP header, we recommend taking advantage of this rather than rolling your own solution if possible.

Request Headers

There are a number of HTTP headers to take advantage of with Orchestrate:

  • If-Match Can be used with KV and Event PUT requests to specify a pre-condition for the store operation to succeed. For more information, see here).

  • If-None-Match Similar to the If-Match header, this header can be used with KV requests to specify that an object with that key must not already exist for the store to succeed. For more information, see here).

  • Accept-Encoding By supplying this header with the value gzip we will deliver the JSON response with GZip compression.

Response Headers

There are also a few standard HTTP headers to take note of and a few unusual ones to capture in the REST client from an Orchestrate API response:

  • ETag This contains a hash which uniquely identifies the object stored with a KV PUT operation. All KV data stored to Orchestrate is immutable. This hash value (we call a “Ref”) can be used with the ‘If-Match’ header as the pre-condition for the next store operation for that key to succeed.

  • Location An absolute path to a newly created KV object, or event object.

  • Content-Location An absolute path to the permanent location of an item’s ref. If you issue a GET request to an item to get its latest value, the Content-Location will be returned as a header that points to the permanent location for the item’s latest ref.

  • X-ORCHESTRATE-REQ-ID A custom header that returns the ID for the request that we use internally at Orchestrate to track the operation and to debug the individual HTTP request. This header can be worth capturing in a client in the event of an error.

  • Link In requests that return multiple objects as part of the response, we return the Link headers for “next” and “prev” to help when building the URL for the next request when paginating through the result set.

URI and Parameter Encoding

The resource path structure in the Orchestrate API follow a common pattern:


The path parameters “collection”, “key”, “type”, “kind”, (and others) as well as query parameters such as “query” should be URL-encoded.

Error Handling

In the event that an error of some kind occurs Orchestrate will return error responses in JSON format. This information is worth parsing into a data object of some kind that gets exposed by the client library.

Most errors are easy to sort and indicate some kind of programmer error like the example below:

  "message": "The item has been stored but conflicts were detected when indexing. Conflicting fields have not been indexed.",
   "details": {
      "conflicts": {
           "firstname": {
               "type": "long",
               "expected": "string"
       "conflicts_uri": "/v0/users/john/refs/5b9af98d6195a5d9/conflicts"
   "code": "indexing_conflict"

Response Codes

Every Orchestrate response is a HTTP response and we use the HTTP status code to provide information on any error that occurs. Successful requests always return a 200-range status code. In the event of non-success responses, we also provide a JSON field “code” with more specific error information wherever possible. The full list of our custom error response codes can be found here.

Next Steps

With the information we have provided in this post, you should now be able to understand how Orchestrate clients are built. If you are very ambitious, you can even begin writing one yourself. For more help and inspiration when creating your Orchestrate REST client, have a look at some of our open-source clients on GitHub:

If you need any assistance or have questions, there’s a “Contact us” option in the Dashboard where you can get support and give feedback at any time. We have a HipChat Community channel where you can find us throughout the day or email us at [email protected]. We’re happy to answer questions, look at code, and point you to resources.

Most of all, have fun building great things with Orchestrate.