REST API

The Crums Timechain REST API is documented on this page.

URI Endpoints

The methods in this API can all be accessed via HTTP GET. Even when the HTTP call causes a change in state of the system or causes a new resource (eg crumtrail artifacts) to be created. This is not RESTy, as a GET call is supposed to be a verb that has no side effects (reads but doesn't touch); but it's convenient. Think of the choice of HTTP method in this REST API as a transport layer concern: it doesn't have verb semantics.

Response

The response format is JSON. With one notable exeception, the HTTP response status is always 200 (OK); the exception is when the system witnesses a hash it doesn't remember seeing: in that case, the an HTTP 202 (Accepted) since a new record is in the process of being created. (See below).

Why JSON?

There's a good argument for a binary response format: the hash proofs are complicated, validating them requires deep knowledge of their structures, and tho JSON is human readable, it's still hard to interpret. So why bother?

  • JSON is easier to handle, and being text, more "transport" friendly. Importantly, it can be annotated with notes, and maybe even app-specific data, without breaking anything.
  • With use the hash proofs seem less complicated. They share a lot of similar parts. Tho a user may never manually parse these parts themselves, the JSON helps build a mental picture of how the hash proofs are structured. (We might provide a mode that breaks block proofs into parts, so a user can more easily see how the hashes in a chain's block proof evolve over time, but presently, that's beyond scope.)
  • The aim is to port this library to other programming languages (under the same license): in that event, porting the existing JSON parsers from Java to another language should provide a good first step.
  • Finally, JSON is relatively URL-freindly. This will prove convenient for encoding hash proofs as URLs. This way, one can consider hosting proof validation tools at a trusted site, for example.


/api/witness
Description

Accepts a new SHA-256 hash to be witnessed in the timechain and returns a crum as reciept. (A crum is a tuple consisting of a 32-byte hash, and an 8-byte UTC witness time). The returned crum may be later used to retrieve a crumtrail via the "update" method. The HTTP response is 202.

This method is idempotent over the duration of a [timechain] block. (The no. of blocks this idempotency is in effect can be configured in the timechain settings, but there's no reason to, since increasing it negatively impacts scalability, but does not offer any tangible user benefit.)

In rare cases (a race between clients), this method may return a 200 response with a fully constructed crumtrail (see update). To cover such corner cases, the optional query string parameters the update method takes, may also be supplied.

Method GET
Paramaters
hash SHA-256 hash of the object, expressed in either 64 hex digits, or 43 base64-32 (b64) digits.
enc Optional. Encoding used to represent 32-byte hashes in JSON response. There are 2 choices: hex and b64 (the default).
Example
/api/witness?enc=hex&hash=41f4915e20..
/api/update
Description

Retrieves the crumtrail for the given crum (previously received via the witness method), if the crum's block no. has been committed to the timechain; otherwise, if the crum is valid (is scheduled to be committed to the timechain), then the crum is returned as-is. Finally, if the crum is not valid (is expired, or made up), then this method defaults to the witness method.

Method GET
Paramaters
hash SHA-256 hash of the object, expressed in either 64 hex digits, or 43 base64-32 (b64) digits.
utc UTC time hash was witnessed in milliseconds.
enc Optional. Encoding used to represent 32-byte hashes in JSON response. There are 2 choices: hex and b64 (the default).
block Optional. Block no. chain block proof begins at. Must be no greater than the block no. utc parameter falls in. Defaults to 1.
compress Optional. Sets the compression-level of the block proof. There are two levels: 0 (no compression), and 1 (the default). The byte size of uncompressed block proofs scales as O (log n)2, where n is the no. of block no.s spanned; compressed block proofs scale as O (log log n) x log n.
/api/state
Description

Returns a block proof asserting the hash of a block at some no. is derived from the hash of blocks at lower no.s. If no arguments are provided, a block proof linking the genesis to the latest block is returned.

Method GET
Paramaters
enc Optional. Encoding used to represent 32-byte hashes in JSON response. There are 2 choices: hex and b64 (the default).
block Optional. Target block no.(s) to be included in block proof. By default, both the genesis and latest block no.s are included.
last Optional. If true (case ignored), then the latest committed block is included in the proof. By default, the latest committed block is included.
compress Optional. Sets the compression-level of the block proof. There are two levels: 0 (no compression), and 1 (the default). The byte size of uncompressed block proofs scales as O (log n)2, where n is the no. of block no.s spanned; compressed block proofs scale as O (log log n) x log n.
Response Block proof and chain parameters in JSON. The block proof is formatted exactly as that found in the block-proof section of a crumtrail's JSON.
Example
/api/state
/api/policy
Description

Returns the chain paramaters and notary policy settings. These are constant, static values over a typical session. The chain parameters (inception UTC, time-bin resolution) are in fact immutable, but other policy settings may be adjusted over the life of a timechain. While the JSON response is meant to be parsed by software, it's somewhat human readable:

  • incept_utc - Starting UTC of genesis block, in milliseconds.
  • bin_exp - Block durations (in milliseconds) and block time boundaries are modeled by powers of 2. This value, called the "bin exponent" defines which power of 2 is used for the time binning. Examples:
    • 10: 210 = 1024 (millis) ~ 1 second
    • 16: 216 ~ 1 minute, 6 seconds
  • The bin exponent also delineates block time boundaries. For a given block, the minimum (big endian) UTC value has its rightmost bin_exp-bits set to 0 (zero), while all eligible UTC values in the block share the same remaining leftmost bits; and the maximum UTC value in the block has its rightmost bin_exp-bits set to 1 (one).

  • block_commit_lag - No. of (wall time) milliseconds post a time block before it becomes eligible to be committed. This, in turn, defines the minimum time that must elapse before a witnessed hash can be updated to become a crumtrail.
  • blocks_searched - When witnessing a new hash, a service may guarantee it hasn't seen that same hash within a certain window of blocks. In most cases, this "feature" is unnecessary and may even be set to zero.
  • blocks_retained - Crumtrails are kept around for this many blocks after their hashes are committed to the chain: after that they are purged.
Method GET
Example
/api/policy

Utilities

The following utility methods are included. These are not strictly part of the timechain API. They are included as convenience methods for human interaction.


/api/util/verify
Description

Verifies the given URL-encoded crumtrail is committed to the timechain. The response (in JSON) is the same crumtrail, but with its block proof patched to the most recent state of the chain. A human readable summary precedes the crumtrail's JSON.

This method primarily exists so that a crumtrail may be archived as a bookmark. See the crum CLI tool for archiving crumtrails from multiple timechains.

Method GET
Paramaters
crumtrail URL-encoded crumtrail JSON.
Example
Since the state of a timechain is not known in advance (and since this page is static), a ready made example cannot be provided. The "Bookmark crumtrail" link on the landing page, is an example.
/api/util/h_codec
Description

Hash encoding translator. Converts hex to b64, and viceversa. The Base64 encoding is non-standard The response is plain text.

About b64

This is slightly non-standard Base64 encoding. It uses the URL / filename-friendly character-set specified in §5 of RFC 4648 but takes liberties (discussed tho not condoned in §3.2) for specifying boundary conditions in a way that does not require padding for our use case. Unlike in some other variants, padding bits must be set to '0', so as to preserve one-to-one-ness, and are pre-pended (two '0' bits), not post-pended.

Method GET
Paramaters
hash Either 64 hex digits, or 43 base64-32 (b64) digits.
Example
/api/util/h_codec?hash=47qaLuWWGx3EKUCKMGpwhAblOQ1D3oRHq5yKD7cm2Na

GNU Affero General Public License v3 (AGPLv3)

© 2020-2024 crums.io