Back to Blog

Getting Started with Anchora: Your First Blockchain Anchor

A step-by-step developer tutorial to create your first blockchain-anchored record with Anchora. From API key to verified proof in 5 minutes.

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
Prerequisites: Node.js 18+ installed, basic JavaScript knowledge. No blockchain experience required!

Step 1: Get Your API Key

First, sign up for a free Anchora account and get your API key:

  1. Go to the Anchora Dashboard
  2. Sign up with email or GitHub
  3. Create a new project (e.g., "My First Project")
  4. Copy your API key from the dashboard
Free Tier: 10,000 records per month free. No credit card required. Perfect for development and testing.

Step 2: Set Up Your Project

Create a new Node.js project and install the Anchora SDK:

Terminal
# 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:

JavaScript - anchor.js
// 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:

Terminal
node anchor.js

You should see output like:

Output
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:

JavaScript - get-proof.js
// 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:

Output
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...
Blockchain Explorer: Click the Polygon link to see your transaction on the public blockchain. Anyone can verify this proof exists!

Step 5: Verify Your Data

Now the crucial part - verify that your data hasn't been tampered with:

JavaScript - verify.js
// 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:

JavaScript
// 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:

JavaScript - with-webhook.js
// 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:

JavaScript - sdk-example.js
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:

JavaScript
// 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:

JavaScript - invoice-system.js
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:

Read the API Documentation

Explore all endpoints, parameters, and response formats

Add Encryption

Protect sensitive data with AES-256-GCM encryption

Set Up Webhooks

Receive real-time notifications when records are anchored

Use Batch Anchoring

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