Skip to main content

Create a Timestamp

The Timestamp API will help you to timestamp individual data, track document versions, and validate already existing timestamps.

This is achieved through two functionalities:

  • Timestamps: Designed for single-point-in-time data anchoring, offering an immutable record of your data's existence on the blockchain.
  • Records: Introduce an enhanced layer of traceability by timestamping various versions of a document under a single record identifier, providing a holistic view of its history.
info

Consult the Timestamp API page for API instructions on how to timestamp documents and events onto the EBSI ledger.

Creating Timestamps: A Step-by-Step Guide

Step 1. Request an access token

Request an access token to the authorisation API with the scope timestamp_write.

API CALL

Request an access token with the scope openid timestamp_write by following the Access Control flow:

Step 2. Create a Timestamp

  1. Interact with Timestamp API to timestamp some data.
API CALL

Build the timestamp transaction with the timestampHashes method of the Timestamp JSON-RPC API, then sign and submit it with the sendSignedTransaction method (see Signing and submitting transactions).

Output
{
"data": {
"test": "some data"
},
"id": "uEiAQjTSfJoekQZpuNe43jEm11_VFCSNagLOqsk81Tnf-aQ"
}
  1. Check the timestamped data.
API CALL

Retrieve it with Get a timestamp (GET /timestamp/v4/timestamps/{timestampId}). The timestampId is the multibase base64url encoding of the multihash of the SHA-256 of your original hash.

Output
{
"hash": "mEiCFEY+9nffGmiCIEU1angy1JvIkLayCumzH2TfYLqCLDw",
"timestampedBy": "0xA4B6C8710f6bF233b8b480498916DEC224A5a891",
"blockNumber": 4024912,
"timestamp": "2023-12-15T16:49:09.000Z",
"data": "0x7b2274657374223a22736f6d652064617461227d",
"transactionHash": "0x19197878626e114811a4011d0d3ff432eaacbdd5eb37466f1b94f73ff03066de"
}
success

Congratulations! You have timestamped data using the Timestamp API.

Records

With the Timestamp API you can also create records containing a history of changes of specific data. Let's see an example.

  1. Create a new record with some data.
API CALL

Build the record-creation transaction with the timestampRecordHashes method of the Timestamp JSON-RPC API, then sign and submit it with the sendSignedTransaction method.

Output
Timestamp record hashes. Record Id:

{
"blockNumber": "0x3d6a55",
"recordId": "0x07b041928382a488c150840cd1c7a24f6b658a82d969961be831c820fd998842",
"multibase64urlRecordId": "uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI",
"hashValue": "0x37926887dc319ac87cda01caf411bccb9ab8933d97cf3c2d57d3e13aa8bad580"
}
  1. Timestamp new data using this record ID.
API CALL

Add a new version with the timestampRecordVersionHashes method of the Timestamp JSON-RPC API — use appendRecordVersionHashes to add hashes to an existing version — then sign and submit it with the sendSignedTransaction method.

  1. Get the versions stored in the record.
API CALL

Fetch the record itself with Get a record (GET /timestamp/v4/records/{recordId}).

Output
{
"ownerIds": ["0xa4b6c8710f6bf233b8b480498916dec224a5a891"],
"revokedOwnerIds": [],
"firstVersionTimestamps": [
"0x37926887dc319ac87cda01caf411bccb9ab8933d97cf3c2d57d3e13aa8bad580"
],
"lastVersionTimestamps": [
"0x66f27c170fb85e96b253673d035214528929f952424d0e5ab4125f4172d6c696"
],
"totalVersions": 2
}
API CALL

List its versions with List a record's versions (GET /timestamp/v4/records/{recordId}/versions).

Output
{
"self": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions?page[after]=1&page[size]=10",
"items": [
{
"versionId": 0,
"href": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions/0"
},
{
"versionId": 1,
"href": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions/1"
}
],
"total": 2,
"pageSize": 10,
"links": {
"first": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions?page[after]=1&page[size]=10",
"prev": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions?page[after]=1&page[size]=10",
"next": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions?page[after]=1&page[size]=10",
"last": "https://api-pilot.ebsi.eu/timestamp/v4/records/uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI/versions?page[after]=1&page[size]=10"
}
}
API CALL

Inspect a single version with Get a version (GET /timestamp/v4/records/{recordId}/versions/{versionId}) to see its hashes and info.

Output
{
"hashes": [
"0x37926887dc319ac87cda01caf411bccb9ab8933d97cf3c2d57d3e13aa8bad580"
],
"info": [
{
"info": "57b1b531f1535d5214c42551"
}
]
}
  1. Compute the multibase64url of the sha256 of this hash.
note

This identifier is computed locally, no API call required: take the SHA-256 of the hash, wrap it as a multihash, and encode the result as multibase base64url (the u prefix). This is the timestampId used in the next step.

  1. Get the timestamp.
API CALL

Fetch it with Get a timestamp (GET /timestamp/v4/timestamps/{timestampId}).

Output
{
"hash": "mEiA3kmiH3DGayHzaAcr0EbzLmriTPZfPPC1X0+E6qLrVgA",
"timestampedBy": "0xA4B6C8710f6bF233b8b480498916DEC224A5a891",
"blockNumber": 4024917,
"timestamp": "2023-12-15T16:49:49.000Z",
"data": "0x7b2264617461223a226d792064617461227d",
"transactionHash": "0xc0e703f2791487d9ef5982926c7a9c064d3cb053fba8640610b7959c13893896"
}
note

The data field is the hex-encoded JSON-LD you timestamped. Decode it to recover the original payload.

Output
{ "my_data": "my data" }
  1. At the same time you can compute the record ID from address, blockNumber, and hash (this hash must be the first version of the record).
note

The recordId is also derived locally: ABI-encode the owner address, the blockNumber, and the first-version hash, take the SHA-256 of the result, and encode the first 32 bytes as multibase base64url.