January 20, 2025 5 min read

How to Integrate Blockchain Certificate Verification into Your Application

A technical guide for developers on integrating OnChainCert's blockchain certificate verification API into web applications, LMS platforms, and HR systems.

Overview

This guide walks through integrating blockchain certificate verification into your application. Whether you’re building an HR system, learning management platform, or credential verification portal, you’ll learn how to verify certificates programmatically.

Prerequisites

Before starting, ensure you have:

  • Basic understanding of REST APIs
  • Familiarity with JavaScript/TypeScript (examples provided)
  • Access to OnChainCert API credentials
  • A Polygon RPC endpoint (optional for direct blockchain queries)

Architecture Overview

OnChainCert provides two verification methods:

MethodUse CaseResponse TimeCost
API VerificationMost applications100-500msFree tier available
Direct BlockchainHigh-security needs1-3 secondsGas fees apply

For most integrations, API verification provides the best balance of speed and reliability.

Quick Start: API Verification

Step 1: Obtain API Credentials

Register at OnChainCert Developer Portal to receive:

  • API Key (public, safe for frontend)
  • API Secret (private, server-side only)

Step 2: Basic Verification Request

const verifyCertificate = async (certificateHash) => {
  const response = await fetch(
    `https://api.onchaincert.org/v1/verify/${certificateHash}`,
    {
      headers: {
        'X-API-Key': process.env.ONCHAINCERT_API_KEY,
      },
    }
  );
  
  return response.json();
};

Step 3: Handle the Response

A successful verification returns:

{
  "valid": true,
  "certificate": {
    "hash": "0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069",
    "recipient": "John Doe",
    "title": "Advanced Web Development",
    "issuer": {
      "name": "Tech Academy",
      "verified": true,
      "walletAddress": "0x..."
    },
    "issuedAt": "2025-01-15T10:30:00Z",
    "blockchain": {
      "network": "polygon",
      "transactionHash": "0x...",
      "blockNumber": 12345678
    }
  }
}

Integration Patterns

Pattern 1: LMS Integration

For Learning Management Systems, integrate verification at course completion:

class CertificateService {
  async issueCertificate(courseId, userId) {
    const course = await this.getCourse(courseId);
    const user = await this.getUser(userId);
    
    const certificateData = {
      recipient: user.fullName,
      email: user.email,
      title: course.certificateTitle,
      description: course.description,
      completedAt: new Date().toISOString(),
      metadata: {
        courseId,
        score: user.finalScore,
        hoursCompleted: course.duration,
      },
    };
    
    const response = await fetch('https://api.onchaincert.org/v1/issue', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.ONCHAINCERT_API_KEY,
        'X-API-Secret': process.env.ONCHAINCERT_API_SECRET,
      },
      body: JSON.stringify(certificateData),
    });
    
    return response.json();
  }
}

Pattern 2: HR System Verification

For applicant credential verification during hiring:

const verifyApplicantCredentials = async (applicant) => {
  const verificationResults = await Promise.all(
    applicant.certificates.map(async (cert) => {
      const result = await verifyCertificate(cert.hash);
      return {
        claimed: cert.title,
        verified: result.valid,
        issuer: result.certificate?.issuer?.name,
        match: result.certificate?.recipient === applicant.name,
      };
    })
  );
  
  return {
    applicantId: applicant.id,
    totalCertificates: verificationResults.length,
    verified: verificationResults.filter(r => r.verified && r.match).length,
    flagged: verificationResults.filter(r => !r.verified || !r.match),
  };
};

Pattern 3: Public Verification Portal

For building a public-facing verification page:

// React component example
function VerificationPortal() {
  const [hash, setHash] = useState('');
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);
  
  const handleVerify = async () => {
    setLoading(true);
    try {
      const response = await fetch(`/api/verify?hash=${hash}`);
      const data = await response.json();
      setResult(data);
    } finally {
      setLoading(false);
    }
  };
  
  return (
    <div>
      <input 
        value={hash}
        onChange={(e) => setHash(e.target.value)}
        placeholder="Enter certificate hash or URL"
      />
      <button onClick={handleVerify} disabled={loading}>
        {loading ? 'Verifying...' : 'Verify Certificate'}
      </button>
      {result && <VerificationResult data={result} />}
    </div>
  );
}

Direct Blockchain Verification

For applications requiring maximum security and trustlessness:

import { ethers } from 'ethers';

const ONCHAINCERT_CONTRACT = '0x...'; // Contract address on Polygon

const ABI = [
  'function verifyCertificate(bytes32 hash) view returns (bool valid, address issuer, uint256 timestamp)',
];

const verifyOnChain = async (certificateHash) => {
  const provider = new ethers.JsonRpcProvider(
    process.env.POLYGON_RPC_URL
  );
  
  const contract = new ethers.Contract(
    ONCHAINCERT_CONTRACT,
    ABI,
    provider
  );
  
  const [valid, issuer, timestamp] = await contract.verifyCertificate(
    certificateHash
  );
  
  return {
    valid,
    issuer,
    issuedAt: new Date(timestamp * 1000),
  };
};

Error Handling

Common error responses and how to handle them:

Error CodeMeaningAction
404Certificate not foundCheck hash format, may be invalid
410Certificate revokedDisplay revocation notice
429Rate limit exceededImplement exponential backoff
500Server errorRetry with backoff, contact support
const verifyWithErrorHandling = async (hash) => {
  try {
    const result = await verifyCertificate(hash);
    return { success: true, data: result };
  } catch (error) {
    if (error.status === 404) {
      return { success: false, error: 'Certificate not found' };
    }
    if (error.status === 410) {
      return { success: false, error: 'Certificate has been revoked', revoked: true };
    }
    if (error.status === 429) {
      await sleep(1000);
      return verifyWithErrorHandling(hash);
    }
    throw error;
  }
};

Webhooks for Real-Time Updates

Subscribe to certificate events:

// Webhook endpoint configuration
app.post('/webhooks/onchaincert', (req, res) => {
  const { event, data } = req.body;
  
  switch (event) {
    case 'certificate.issued':
      handleNewCertificate(data);
      break;
    case 'certificate.revoked':
      handleRevocation(data);
      break;
    case 'issuer.verified':
      handleIssuerVerification(data);
      break;
  }
  
  res.status(200).send('OK');
});

Security Best Practices

  1. Never expose API secrets in frontend code
  2. Validate certificate hashes before querying
  3. Implement rate limiting on your verification endpoints
  4. Cache verification results appropriately (5-15 minutes recommended)
  5. Log all verification attempts for audit trails

Testing

Use the sandbox environment for development:

const API_BASE = process.env.NODE_ENV === 'production'
  ? 'https://api.onchaincert.org'
  : 'https://sandbox.onchaincert.org';

Sandbox provides test certificates and simulated blockchain responses without real transactions.

Next Steps


This guide is maintained by the OnChainCert engineering team. For technical support, contact [email protected]

OnChainCert Team

OnChainCert

Related Articles

Ready to Issue Blockchain Certificates?

Start issuing tamper-proof certificates today. Free trial, no credit card required.

Get Started Free