What You'll Build
By the end of this tutorial, you'll have:
- Created your first blockchain-anchored record
- Received a cryptographic proof from the Polygon blockchain
- Verified your data hasn't been tampered with
- Understood the complete anchoring lifecycle
Step 1: Get Your API Key
First, sign up for a free Anchora account and get your API key:
- Go to the Anchora Dashboard
- Sign up with email or GitHub
- Create a new project (e.g., "My First Project")
- Copy your API key from the dashboard
Step 2: Set Up Your Project
Create a new Node.js project and install the Anchora SDK:
# Create a new directory
mkdir anchora-demo && cd anchora-demo
# Initialize npm project
npm init -y
# Install the Anchora SDK
npm install @anchora/sdk
# Create environment file
echo "ANCHORA_API_KEY=your_api_key_here" > .env
# Install dotenv for environment variables
npm install dotenv
Step 3: Anchor Your First Record
Create a file called anchor.js and add the following code:
// anchor.js
require('dotenv').config();
const ANCHORA_API_KEY = process.env.ANCHORA_API_KEY;
const API_BASE = 'https://api.anchora.io';
async function anchorRecord() {
// The data you want to anchor
const myData = {
documentId: 'DOC-001',
title: 'My First Blockchain Record',
content: 'This data will be anchored to the Polygon blockchain!',
author: 'Developer',
timestamp: new Date().toISOString()
};
console.log('Anchoring data...');
console.log('Data:', JSON.stringify(myData, null, 2));
try {
// Call the Anchora API
const response = await fetch(`${API_BASE}/v1/anchor`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ANCHORA_API_KEY}`
},
body: JSON.stringify({
data: myData,
collection: 'my-documents'
})
});
const result = await response.json();
if (result.success) {
console.log('\n✓ Record anchored successfully!');
console.log('Hash:', result.hash);
console.log('Record ID:', result.recordId);
console.log('Status:', result.status);
console.log('\nYour record is now queued for blockchain anchoring.');
console.log('This typically takes 30-60 seconds.');
// Save the hash for later verification
return result;
} else {
console.error('Error:', result.message);
}
} catch (error) {
console.error('Request failed:', error.message);
}
}
// Run the anchor function
anchorRecord();
Run the script:
node anchor.js
You should see output like:
Anchoring data...
Data: {
"documentId": "DOC-001",
"title": "My First Blockchain Record",
"content": "This data will be anchored to the Polygon blockchain!",
"author": "Developer",
"timestamp": "2026-01-29T10:30:00.000Z"
}
✓ Record anchored successfully!
Hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Record ID: 673d8f9a2c4e5f1a2b3c4d5e
Status: QUEUED
Your record is now queued for blockchain anchoring.
This typically takes 30-60 seconds.
Step 4: Get the Blockchain Proof
After anchoring (30-60 seconds), retrieve the blockchain proof:
// get-proof.js
require('dotenv').config();
const ANCHORA_API_KEY = process.env.ANCHORA_API_KEY;
const API_BASE = 'https://api.anchora.io';
// Replace with your hash from Step 3
const HASH = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
async function getProof() {
console.log('Fetching blockchain proof...');
const response = await fetch(`${API_BASE}/v1/proof/${HASH}`, {
headers: {
'Authorization': `Bearer ${ANCHORA_API_KEY}`
}
});
const result = await response.json();
if (result.success) {
console.log('\n✓ Blockchain proof retrieved!');
console.log('\n--- Proof Details ---');
console.log('Hash:', result.hash);
console.log('Status:', result.status);
console.log('Block Number:', result.proof.blockNumber);
console.log('Transaction Hash:', result.proof.transactionHash);
console.log('Merkle Root:', result.proof.merkleRoot);
console.log('Merkle Proof:', result.proof.merkleProof);
console.log('Anchored At:', result.proof.anchoredAt);
// View on blockchain explorer
const explorerUrl = `https://polygonscan.com/tx/${result.proof.transactionHash}`;
console.log('\nView on Polygon:', explorerUrl);
return result;
} else if (result.status === 'QUEUED') {
console.log('Record is still being processed. Try again in 30 seconds.');
} else {
console.error('Error:', result.message);
}
}
getProof();
Output after anchoring completes:
Fetching blockchain proof...
✓ Blockchain proof retrieved!
--- Proof Details ---
Hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Status: ANCHORED
Block Number: 45123789
Transaction Hash: 0xb706858a2c9e4a8e3d5f9c1a2b3d4e5f6789...
Merkle Root: 0x9876543210fedcba9876543210fedcba...
Merkle Proof: ["0x1234...", "0x5678...", "0x9abc..."]
Anchored At: 2026-01-29T10:30:45.000Z
View on Polygon: https://polygonscan.com/tx/0xb706858a2c9e4a8e3d5f9c1a2b3d4e5f6789...
Step 5: Verify Your Data
Now the crucial part - verify that your data hasn't been tampered with:
// verify.js
require('dotenv').config();
const ANCHORA_API_KEY = process.env.ANCHORA_API_KEY;
const API_BASE = 'https://api.anchora.io';
async function verifyData() {
// The EXACT same data you anchored
const originalData = {
documentId: 'DOC-001',
title: 'My First Blockchain Record',
content: 'This data will be anchored to the Polygon blockchain!',
author: 'Developer',
timestamp: '2026-01-29T10:30:00.000Z' // Use exact timestamp
};
// The proof data from Step 4
const proofData = {
hash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
blockNumber: 45123789,
merkleProof: ['0x1234...', '0x5678...', '0x9abc...']
};
console.log('Verifying data integrity...');
const response = await fetch(`${API_BASE}/v1/verify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ANCHORA_API_KEY}`
},
body: JSON.stringify({
data: originalData,
hash: proofData.hash,
blockNumber: proofData.blockNumber,
merkleProof: proofData.merkleProof
})
});
const result = await response.json();
if (result.verified) {
console.log('\n✓ VERIFIED: Data integrity confirmed!');
console.log('Status:', result.status);
console.log('Message:', result.message);
console.log('\nThis data has not been tampered with since it was anchored.');
} else {
console.log('\n✗ TAMPERED: Data integrity check FAILED!');
console.log('Status:', result.status);
console.log('Message:', result.message);
console.log('\nWARNING: The data has been modified!');
}
}
verifyData();
Test Tampering Detection
Try modifying the data slightly and verify again - you'll see the tampering is detected:
// Tampered data (changed "Developer" to "Hacker")
const tamperedData = {
documentId: 'DOC-001',
title: 'My First Blockchain Record',
content: 'This data will be anchored to the Polygon blockchain!',
author: 'Hacker', // ← Changed!
timestamp: '2026-01-29T10:30:00.000Z'
};
// Verification will FAIL:
// ✗ TAMPERED: Data integrity check FAILED!
// Status: TAMPERED
// Message: Data has been modified. Hash mismatch.
Using Webhooks (Recommended)
Instead of polling for proof, set up a webhook to receive notifications when your record is anchored:
// Anchor with webhook
const response = await fetch(`${API_BASE}/v1/anchor`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ANCHORA_API_KEY}`
},
body: JSON.stringify({
data: myData,
collection: 'my-documents',
webhookUrl: 'https://your-app.com/webhooks/anchora' // ← Add this
})
});
// Your webhook endpoint receives:
// POST /webhooks/anchora
// {
// "type": "ANCHORED",
// "hash": "e3b0c442...",
// "recordId": "673d8f9a...",
// "blockNumber": 45123789,
// "transactionHash": "0xb706858a...",
// "merkleProof": ["0x1234...", "0x5678..."],
// "anchoredAt": "2026-01-29T10:30:45.000Z"
// }
Using the SDK (Recommended)
For production use, the SDK provides a cleaner API:
import VaaS from '@anchora/sdk';
// Initialize the client
const vaas = new VaaS({
apiKey: process.env.ANCHORA_API_KEY
});
// Anchor data
const result = await vaas.anchor({
data: {
documentId: 'DOC-001',
title: 'My Document',
content: 'Important data'
},
collection: 'documents'
});
console.log('Hash:', result.hash);
// Wait for anchoring (optional)
const proof = await vaas.waitForAnchoring(result.hash);
console.log('Block:', proof.blockNumber);
// Verify data
const verification = await vaas.verify({
data: myData,
hash: result.hash
});
console.log('Verified:', verification.verified); // true
Adding Encryption (Optional)
For sensitive data, add encryption:
// Anchor with encryption
const result = await vaas.anchor({
data: {
patientId: 'P-12345',
diagnosis: 'Sensitive medical information',
treatment: 'Confidential treatment plan'
},
collection: 'medical-records',
encrypt: true, // ← Enable encryption
encryptionKey: process.env.ENCRYPTION_KEY // 32+ characters
});
// Data is encrypted with AES-256-GCM before storage
// Hash is computed from ORIGINAL data (before encryption)
// You need the encryption key to decrypt and verify
Complete Example: Invoice Verification System
Here's a complete example of an invoice verification system:
import VaaS from '@anchora/sdk';
const vaas = new VaaS({
apiKey: process.env.ANCHORA_API_KEY
});
// Create and anchor an invoice
async function createInvoice(invoiceData) {
const invoice = {
invoiceId: generateInvoiceId(),
...invoiceData,
createdAt: new Date().toISOString()
};
// Anchor to blockchain
const anchor = await vaas.anchor({
data: invoice,
collection: 'invoices',
webhookUrl: 'https://myapp.com/webhooks/anchora'
});
// Save to database with anchor info
await db.invoices.create({
...invoice,
anchora: {
hash: anchor.hash,
recordId: anchor.recordId,
status: anchor.status
}
});
return invoice;
}
// Verify an invoice hasn't been tampered with
async function verifyInvoice(invoiceId) {
// Get invoice from database
const invoice = await db.invoices.findOne({ invoiceId });
if (!invoice) {
throw new Error('Invoice not found');
}
// Get blockchain proof
const proof = await vaas.getProof(invoice.anchora.hash);
// Verify the invoice data matches the blockchain
const verification = await vaas.verify({
data: {
invoiceId: invoice.invoiceId,
customer: invoice.customer,
amount: invoice.amount,
items: invoice.items,
createdAt: invoice.createdAt
},
hash: invoice.anchora.hash,
blockNumber: proof.blockNumber,
merkleProof: proof.merkleProof
});
return {
invoiceId,
verified: verification.verified,
blockNumber: proof.blockNumber,
anchoredAt: proof.anchoredAt,
explorerUrl: `https://polygonscan.com/tx/${proof.transactionHash}`
};
}
// Usage
const invoice = await createInvoice({
customer: 'Acme Corp',
amount: 1500.00,
items: [
{ description: 'Consulting', price: 1000 },
{ description: 'Support', price: 500 }
]
});
console.log('Invoice created:', invoice.invoiceId);
// Later: Verify the invoice
const result = await verifyInvoice(invoice.invoiceId);
console.log('Verified:', result.verified);
Next Steps
Congratulations! You've created your first blockchain-anchored record. Here's what to explore next:
Explore all endpoints, parameters, and response formats
Protect sensitive data with AES-256-GCM encryption
Receive real-time notifications when records are anchored
Anchor multiple records in a single API call for efficiency
Ready to build tamper-proof applications?
You've learned the basics. Now build something amazing! The free tier includes 10,000 records per month.
Get Your API Key