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.
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.
Request an access token with the scope openid timestamp_write by following the Access Control flow:
- GET Presentation definition: fetch the presentation definition for the scope.
- POST Token endpoint: submit a presentation matching the definition to obtain the token.
Step 2. Create a Timestamp
- Interact with Timestamp API to timestamp some data.
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).
{
"data": {
"test": "some data"
},
"id": "uEiAQjTSfJoekQZpuNe43jEm11_VFCSNagLOqsk81Tnf-aQ"
}
- Check the timestamped data.
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.
{
"hash": "mEiCFEY+9nffGmiCIEU1angy1JvIkLayCumzH2TfYLqCLDw",
"timestampedBy": "0xA4B6C8710f6bF233b8b480498916DEC224A5a891",
"blockNumber": 4024912,
"timestamp": "2023-12-15T16:49:09.000Z",
"data": "0x7b2274657374223a22736f6d652064617461227d",
"transactionHash": "0x19197878626e114811a4011d0d3ff432eaacbdd5eb37466f1b94f73ff03066de"
}
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.
- Create a new record with some data.
Build the record-creation transaction with the timestampRecordHashes method of the Timestamp JSON-RPC API, then sign and submit it with the sendSignedTransaction method.
Timestamp record hashes. Record Id:
{
"blockNumber": "0x3d6a55",
"recordId": "0x07b041928382a488c150840cd1c7a24f6b658a82d969961be831c820fd998842",
"multibase64urlRecordId": "uB7BBkoOCpIjBUIQM0ceiT2tlioLZaZYb6DHIIP2ZiEI",
"hashValue": "0x37926887dc319ac87cda01caf411bccb9ab8933d97cf3c2d57d3e13aa8bad580"
}
- Timestamp new data using this record ID.
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.
- Get the versions stored in the record.
Fetch the record itself with Get a record (GET /timestamp/v4/records/{recordId}).
{
"ownerIds": ["0xa4b6c8710f6bf233b8b480498916dec224a5a891"],
"revokedOwnerIds": [],
"firstVersionTimestamps": [
"0x37926887dc319ac87cda01caf411bccb9ab8933d97cf3c2d57d3e13aa8bad580"
],
"lastVersionTimestamps": [
"0x66f27c170fb85e96b253673d035214528929f952424d0e5ab4125f4172d6c696"
],
"totalVersions": 2
}
List its versions with List a record's versions (GET /timestamp/v4/records/{recordId}/versions).
{
"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"
}
}
Inspect a single version with Get a version (GET /timestamp/v4/records/{recordId}/versions/{versionId}) to see its hashes and info.
{
"hashes": [
"0x37926887dc319ac87cda01caf411bccb9ab8933d97cf3c2d57d3e13aa8bad580"
],
"info": [
{
"info": "57b1b531f1535d5214c42551"
}
]
}
- Compute the multibase64url of the sha256 of this hash.
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.
- Get the timestamp.
Fetch it with Get a timestamp (GET /timestamp/v4/timestamps/{timestampId}).
{
"hash": "mEiA3kmiH3DGayHzaAcr0EbzLmriTPZfPPC1X0+E6qLrVgA",
"timestampedBy": "0xA4B6C8710f6bF233b8b480498916DEC224A5a891",
"blockNumber": 4024917,
"timestamp": "2023-12-15T16:49:49.000Z",
"data": "0x7b2264617461223a226d792064617461227d",
"transactionHash": "0xc0e703f2791487d9ef5982926c7a9c064d3cb053fba8640610b7959c13893896"
}
The data field is the hex-encoded JSON-LD you timestamped. Decode it to recover the original payload.
{ "my_data": "my data" }
- At the same time you can compute the record ID from
address,blockNumber, andhash(this hash must be the first version of the record).
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.