---
title: "Verify an attestation"
description: "Look up a recorded document or event, then check its anchor on Base yourself."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.sureshake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Verify an attestation

Use this guide to check that a document or event was recorded with Sureshake, and that its anchor exists on Base. You don't need an account. Read [How proof works](/trust/how-proof-works/) first to understand what a successful check does and doesn't tell you.

## Look up a record

1. **Get the hash**

   Use the hash someone gave you, or calculate one from your copy of a document. For a statement of work, the document hash is the SHA-256 of the sealed PDF.

   ```sh
   shasum -a 256 statement-of-work.pdf
   ```
2. **Open the record**

   Go to `https://www.sureshake.com/verify/<hash>`. A document hash lists every event recorded against that document, in order. An event hash shows that single event.
3. **Read the status**

   **Anchored** means the event's batch is confirmed on chain. **Pending anchor** means it is waiting for the next hourly batch, so check back later.

If the page isn't found, Sureshake has no record of that hash. For a document, that can mean your copy differs from the one recorded, or that it was never recorded.

Each event shows its type, the time it **Occurred**, its **Position in history** and the event it **Follows**. Once anchored, it also shows the **Network**, **Batch**, **Block**, **Transaction** and **Batch root**.

## Verify it yourself

The verifier is one readable file with no dependencies. It needs Node.js 18 or later.

1. **Download it**

   ```sh
   curl -O https://www.sureshake.com/verify-attestation.mjs
   ```
2. **Read it**

   Open the file and check what it does before you run it.
3. **Run it**

   ```sh
   node verify-attestation.mjs <hash>
   ```
4. **Read the result**

   Each event prints a line beginning `ok`, `pending` or `FAILED`, and the last line gives the overall result.

   | Last line | Exit code | Meaning |
   | - | - | - |
   | `verified` | 0 | Every event passed |
   | `pending: ...` | 2 | At least one event isn't anchored yet |
   | `NOT verified` | 1 | At least one event failed |

   Only the word `verified` counts as a pass, so don't rely on the exit code alone.
5. **Check the network**

   Confirm each `ok` line says `chain 8453`, which is Base. The script also accepts Sureshake's test network, chain `84532`. A production record never uses it.

> **If the script prints nothing**
>
> The script didn't run its checks, even though it exits with code 0. This
> happens when the path to the file contains a space or a symbolic link, such as
> `/tmp` on macOS. Move the file to a plain folder, such as `~/Downloads`, and
> run it from there.

### What the script checks

For each event, the script:

1. Requires the record to name the registry contract written into the script for that network, rather than trusting the address it was given.
2. Asks that contract, through a public Base node, which batch anchored the record's root and how many events that batch held.
3. Recalculates the root from the event hash and its proof, using an RFC 6962 Merkle tree, and requires an exact match.

### What the script doesn't check

- **That the list of events is complete.** The list comes from Sureshake's API. The script checks the events it is given, and can't detect one that was left out.
- **What the event says.** An event hash covers details held by the parties and the source system. Only someone with those details can recalculate it.
- **That the event's order is correct.** The script doesn't check the order of events. Compare **Position in history** and **Follows event** yourself.

## Check on-chain without the script

The production registry contract is on Base (chain ID 8453):

```text
0x6fe70a649E6408bf5b462C53eFb13C5eFb6C10eb
```

You can [view it on BaseScan](https://basescan.org/address/0x6fe70a649E6408bf5b462C53eFb13C5eFb6C10eb), including each anchoring transaction.

1. **Get the root**

   Copy the **Batch root** from the record page, or `merkleRoot` from this response:

   ```sh
   curl https://api.sureshake.com/v2/attestations/verify/<hash>
   ```
2. **Ask the contract**

   Call `batchOfRoot` through a public Base node. Put the root straight after `0x9575b49c`, which identifies that function:

   ```sh
   curl -s https://mainnet.base.org \
     -H 'content-type: application/json' \
     --data '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x6fe70a649e6408bf5b462c53efb13c5efb6c10eb","data":"0x9575b49c<root>"},"latest"]}'
   ```
3. **Read the answer**

   The `result` holds three 32-byte values in hex: the batch number, the number of events in the batch, and the anchor time in Unix seconds. An `execution reverted` error means the contract never saw that root.

## Check a saved record

Save the API response while it's available, so you can check it later without relying on Sureshake's API:

```sh
curl https://api.sureshake.com/v2/attestations/verify/<hash> -o record.json
node verify-attestation.mjs <hash> --file record.json
```

## Verify an NDA acceptance

When a recipient accepts an NDA on a shared report, Sureshake records that acceptance as an event labelled **NDA accepted for a shared report**. See [sharing](/founders/sharing/) to require an NDA.

As the report's owner, you can open **Access protection** on the share to see who signed and when. It also shows one of these messages, with a link to the record:

- **Fingerprint anchored on Base.** The acceptance is in a confirmed batch.
- **Fingerprint recorded; it is anchored on Base in the next batch.** Check back after the next batch.

The fingerprint covers the report, the share, a hash of the NDA text, a hash of the signer's email and the time of acceptance. The verification page shows none of those details. It shows that an acceptance with this fingerprint was recorded and anchored.

If you change the NDA text, the recipient has to accept it again, which records a new fingerprint.

## What the public can see

The verification page and API show fingerprints, the type of each event, its timing, its order and its anchor. They don't show documents, names, email addresses, the parties, contract values or any other event details.

Because the event type is public, anyone holding a hash can see, for example, that an invoice was marked paid on a certain date. Share hashes only with people who should know that.

## Delivery record

A company that delivers work through a connected system can show a **Delivery record** tab: **SOWs delivered**, **Criteria accepted**, **First-pass acceptance**, **Milestones on time** and **Client retention**. Sureshake calculates it only from anchored events, so it reflects what the connected system reported.

The first-pass rate gives larger engagements more weight and reduces the weight of repeat work with the same client. Below five engagements, rates are shown with their sample size. Client names are never shown.

### Link a delivery source

Linking takes both sides. The connected system proposes that one of its vendor accounts is your company, and an owner or admin decides.

1. **Open your settings**

   Open your company's **Settings** page and find **Delivery record sources**.
   This section appears once a system has proposed a link.
2. **Decide**

   Select **Accept** only if the vendor account is yours, otherwise select
   **Decline**. Nothing counts until you accept. You can **Revoke** a link
   later.

The tab is private to your owners and admins. To show it to other people, add them through viewer groups, and remove them the same way.

Source: https://docs.sureshake.com/trust/verify-attestations/index.mdx
