In this session we’ll be covering one of Orchestrate‘s most powerful features: Refs. A Ref is a content-based hash that acts as a unique identifier pointing to a specific version of an item.

Whether you’re starting with Orchestrate or looking for a refresher, by the end of this article you’ll have a better understanding of what Refs are, what makes them so potent, and how to leverage them in your applications. So let’s crack open our proverbial textbooks and dive into Refs.

Using Refs

Every Key/Value item in Orchestrate is represented by a ref. When you make changes to a Key/Value item, that updated item is stored as a new item with a different ref.

    "path": {
        "collection": "collection",
        "key": "some-key",
        "ref": "c4c3fc3bca065572"
    "value": {
        "field_name": "some_value"

When an item is retrieved by key, the most recent ref and value of that item is returned. When you specify a ref for an item, you’ll get the value of that item at a particular point in time.

What can I do with Refs?

Refs make it trivial to track changes, retrieve previous values of a key, or even restore deleted values. By using refs with conditional PUTs and DELETEs, you can easily manage state when multiple users are changing values in parallel.

Listing Key/Value Refs

Say we run a soda company and have an app that manages our soda recipes. The recipe for our classic flavor has changed over the years and we want to see those changes. We can GET our classic soda recipe by key and return its refs as well as their values:

curl -i "" \
  -u "$api_key:"

Using these results we can compare the different recipe versions and see how popular particular recipes were or the cost of ingredients between versions.

Retrieve A Ref

Building on the soda company example, say we want to release a classic flavor throwback. We can perform a GET for a single ref:

curl -i "$ref" \
  -u "$api_key:"

And get the recipe our classic flavor at that particular point in time.

Managing State

Our team of soda engineers have been hard at work on a new flavor. A few of them are updating the recipe and description at the same time. By leveraging Orchestrate’s Conditional PUTs and refs, we can ensure that conflicts don’t occur:

curl -i "" \
  -XPUT \
  -H "Content-Type: application/json" \
  -H 'If-Match: "ahd48f9364612f20"' \
  -u "$api_key:" \
  -d "$json"

Here we’re using an If-Match header with a ref. This tells Orchestrate to only update awesome-new-flavor‘s value if the provided ref matches the currently stored ref.

Restoring Values

Uh-oh, it looks like one of our soda engineers accidently deleted the final version of the awesome-new-flavor recipe! That’s alright though, because Orchestrate is non-destructive in nearly all cases. When you perform DELETEs on items, rather than remove the entire item, Orchestrate sets the item’s current value to null. This means that all previous versions of the item remain available.

So we can find the final recipe by performing a GET by it’s ref:

curl -i "$ref" \
  -u "$api_key:"

If the ref is unknown we can request the list of refs, then set a limit of one and an offset of one so that it skips the current (deleted) version and returns the previous recipe value:

curl -i "" \
  -u "$api_key:"

Now we have the recipe’s value prior to being deleted and can update accordingly.

Purging Values

Let’s say our soda company doesn’t always hit the mark with flavors. In fact, there’s a flavor that no-one seems to like at all. But for some strange reason, we bring it back into production every few years and try to sell it with the same poor results. After some discussion, it’s decided the best course of action is to remove all traces of the recipe so that we won’t be tempted to revive the flavor yet again.

We can accomplish this task by performing a Purge:

curl -i "" \
    -XDELETE \
    -u "$api_key:"

Purge will permanently delete a Key/Value item and all it’s history. Pretty simple, right?