# Introduction

You can get the latest version of the

Stampery APIclient library for your preferred language on GitHub:

- Node.js → https://github.com/stampery/node
- PHP → https://github.com/stampery/php
- Python → https://github.com/stampery/python
- Ruby → https://github.com/stampery/ruby
- Elixir → https://github.com/stampery/elixir
- Java → https://github.com/stampery/java
- Go → https://github.com/stampery/go

This is the documentation for version 3 of the **Stampery API**, the industrial-scale data certification platform.

With the Stampery API you can certify a virtually **unlimited** amount of datasets or files by embedding their unique identifiers into both the **Bitcoin** and **Ethereum** public blockchains.

For every certification and blockchain, you get a receipt document called **proof** that allows you to prove the timestamped **existence**, **integrity** and **ownership** of the certified data.

Client libraries are available for **NodeJS**, **PHP**, **Python**, **Ruby**, **Elixir**, **Java** and **Go**.

You can view code examples across this documentation in the dark area to the right, and switch between different programming languages with the tabs in the top right.

# Authentication

```
stampery = new Stampery('367c6ec2-5791-4cf5-8094-4bae00c639b4');
```

```
stampery = new Stampery '367c6ec2-5791-4cf5-8094-4bae00c639b4'
```

```
<?
$stampery = include('stampery.inc.php');
$stampery = new Stampery('830fa1bf-bee7-4412-c1d3-31dddba2213d');
```

```
from stampery import Stampery
client = Stampery('2d4cdee7-38b0-4a66-da87-c1ab05b43768', 'prod')
```

```
defmodule MyStampingModule do
use Stampery, {"2d4cdee7-38b0-4a66-da87-c1ab05b43768", :prod}
def on_ready do
end
def on_proof(proof) do
end
def on_error(error) do
end
end
MyStampingModule.start()
```

```
require 'stampery'
stampery = Client.new '2d4cdee7-38b0-4a66-da87-c1ab05b43768'
```

```
import com.stampery.Stampery;
Stampery stampery = new Stampery("2d4cdee7-38b0-4a66-da87-c1ab05b43768");
stampery.subscribe(this);
stampery.start();
```

```
events := stampery.Login("2d4cdee7-38b0-4a66-da87-c1ab05b43768")
```

Authentication is performed by using app-specific **secret tokens**.

You can signup and generate your own secret tokens with the API dashboard.

# Hashing

```
stampery.hash("Hello world!", function(hash) {
console.log(hash);
});
```

```
stampery.hash "Hello world!", (hash) ->
console.log hash
```

```
<?
$digest = $stampery->hash("Hello world!");
echo(hash);
```

```
digest = client.hash("Hello world!")
print(digest)
```

```
digest = MyStampingModule.hash("Hello world!")
IO.puts digest
```

```
digest = stampery.hash "Hello world!"
```

```
digest = stampery.hash("Hello world!");
```

```
digest := stampery.Hash("Hello world!")
```

For your convenience, all our client libraries provide a hash function that takes any kind of string and directly outputs a ready to stamp hash digest.

# Stamping

## Stamping a hash

```
stampery.on('proof', function(hash, proof) {
console.log('Received proof for hash ' + hash, proof);
});
stampery.hash(digest);
```

```
stampery.on 'proof', (hash, proof) ->
console.log "Received proof for hash #{hash}", proof
stampery.stamp digest
```

```
<?
$stampery->stamp($digest);
```

```
client.stamp(digest)
```

```
Stampery.stamp digest
```

```
stampery.stamp digest
```

```
stampery.stamp(digest);
```

```
stampery.Stamp(digest)
```

Our API is capable of stamping **SHA3-512 (FIPS-202)** hashes directly.

For stamping a SHA3-512 hash, you only have to make a call to the `stamp`

method of our API, as seen in the examples to the right.

## Stamping a file

```
stampery.on('proof', function(hash, proof) {
console.log('Received proof for hash ' + hash, proof);
});
fs.readFile('/etc/hosts', 'utf8', function(err, data) {
stampery.hash(data, stampery.stamp);
});
```

```
stampery.on 'proof', (hash, proof) ->
console.log "Received proof for hash #{hash}", proof
fs.readFile '/etc/hosts', 'utf8', (err, data) ->
stampery.hash data, stampery.stamp
```

```
<?
$stampery.on('proof', function(hash, proof){
echo("Received proof for hash" . $hash . "\n");
var_dump($proof);
});
$file = file_get_contents('/path/to/file.txt');
$digest = $stampery->hash($file);
$stampery->stamp($digest);
```

```
def on_proof(hash, proof):
print("Received proof for " + hash)
print(proof)
file = open("/path/to/file.txt")
digest = client.hash(file.read())
client.stamp(digest)
```

```
defmodule MyStampingModule do
use Stampery, {"2d4cdee7-38b0-4a66-da87-c1ab05b43768", :prod}
def on_proof(proof) do
IO.puts("Received proof for hash #{inspect proof.hash}")
IO.inspect(proof)
end
end
{:ok, data} = File.read("/path/to/file.txt")
digest = Stampery.hash(data)
MyStampingModule.stamp(digest)
```

```
stampery.on :proof do |hash, proof|
puts 'Received proof for'
puts hash
puts 'Proof'
puts proof.to_s
end
data = File.read "/path/to/file.txt"
digest = stampery.hash data
stampery.stamp digest
```

```
// the following code should be inside a class that implements our Consumer interface
public void onProof(String hash, Proof proof) {
System.out.println(hash);
System.out.println(proof);
}
public void onReady() {
String file = "";
try{
file = new String(Files.readAllBytes(Paths.get("/path/to/file.txt")));
}catch(IOException e){
e.printStackTrace();
}
String digest = stampery.hash(file);
stampery.stamp(digest);
}
```

```
for event := range events {
switch event.Type {
case "ready":
data, err := ioutil.ReadFile("/path/to/file.txt")
if err != nil {
log.Fatalf("Error %v\n", err)
}
digest := stampery.Hash(string(data))
stampery.Stamp(digest)
case "proof":
fmt.Println("\nProof")
p := event.Data.(stampery.Proof)
fmt.Println("Hash: ", p.Hash)
fmt.Printf("Version: %v\nSiblings: %v\nRoot: %v\n", p.Version, p.Siblings, p.Root)
fmt.Printf("Anchor:\n Chain: %v\n Tx: %v\n", p.Anchor.Chain, p.Anchor.Tx)
case "error":
log.Fatalf("%v\n", event.Data)
}
}
```

Stamping a file is just as easy as obtaining its **SHA3-512** hash and then stamping the hash as explained in the previous section.

For your convenience, all our client libraries include a function for hashing files as seen in the examples to the right.

# Proofs

## About proofs

Proofs are **JSON** documents proving that a certain file or dataset has been anchored to a certain public blockchain.

Anyone holding the original data and its corresponding proof can verify the certification by following the proving process described here.

## Proof format

This is the structure of a proof:

Where `v`

, `s`

, `r`

, `c`

and `t`

are:

Key | Description | Value type |
---|---|---|

v | BTA version used. | Integer(1) |

s | Merkle siblings. | Array |

r | Merkle root. | String(128) |

c | Chain code. | Integer(1) |

t | Transaction ID (txid) | String(64) |

Valid chain codes for `c`

are:

Value | Chain |
---|---|

1 | Bitcoin livenet |

2 | Ethererum livenet |

## Retrieving missed proofs

```
stampery.on('proof', function(hash, proof) {
console.log('Received missed proof for hash ' + hash, proof);
});
stampery.receiveMissedProofs();
```

```
stampery.on 'proof', (hash, proof) ->
console.log "Received missed proof for hash #{hash}", proof
stampery.receiveMissedProofs()
```

If you make a stamp and for some reason disconnect from our service right after, you will miss the proof.

Don’t worry, **missed proofs are queued in our servers for 24h**, and you can retrieve them by making a simple call to the `receiveMissedProofs`

method.

## Checking a proof (proving)

```
stampery.prove(hash, proof, function (valid) {
console.log('Proof validity:', valid);
});
```

```
stampery.prove hash, proof, (valid) ->
console.log 'Proof validity:', valid
```

```
MyStampingModule.prove(proof)
```

We call **proving** to the process of verifying a proof is valid and therefore demonstrating that a hash or file has been undoubtfully embedded in the blockchain and it has not been tampered since then.

Proofs are independently verifiable by everyone in possesion of the hash or file and the proof itself.

The process of proving Stampery proofs made with the current version 5 of our BTA platform is made like this:

- Take the hash
- Take first element in the Merkle siblings list
`s[0]`

- Concatenate both, putting the biggest of them in front
- Hash the resulting string with
`SHA3-512`

- Take the resulting hash and the next element in the Merkle siblings list, concatenate like before and hash the resulting string
- Repeat same process until there are no elements left in the Merkle siblings list
- Check the resuting string matches the Merkle root of the proof,
`r`

- Take the transaction ID,
`t`

, and paste in your favorite Bitcoin/Ethereum chain explorer - Check that the Merkle root,
`r`

, matches the tail of the data embedded in the transaction

If the checks in steps **7** and **9** pass, then you have proved that the proof is OK and the hash or file has not been tampered.