Document Verification
Every document signed through inSigner includes a SHA-256 hash for tamper detection. You can verify that a signed document is authentic and unmodified using the verification API.
How it works
Section titled “How it works”- When a document is uploaded, inSigner computes its SHA-256 hash (the “original hash”).
- When signing is completed, inSigner computes the signed document hash (the “signed hash”).
- You can verify any PDF against these hashes via the API.
Verifying a document
Section titled “Verifying a document”- Compute the SHA-256 hash of the file you want to verify.
- Send it to the verification API to check against inSigner records.
- Check the response —
verified: truemeans the document is authentic.
# Compute the hashSHA256=$(shasum -a 256 "Sales Agreement - Signed.pdf" | awk '{print $1}')
# Verifycurl -X POST https://app.insigner.co/api/v1/verify \ -H "Authorization: Bearer isk_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"hash\": \"$SHA256\"}"import { createHash } from 'crypto';import { readFileSync } from 'fs';
async function verifyDocument(filePath) { // Compute SHA-256 hash const buffer = readFileSync(filePath); const hash = createHash('sha256').update(buffer).digest('hex');
// Verify against inSigner const res = await fetch('https://app.insigner.co/api/v1/verify', { method: 'POST', headers: { 'Authorization': 'Bearer isk_YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ hash }) });
const { data } = await res.json();
if (data.verified) { console.log('✅ Document is authentic'); console.log(` Name: ${data.documentName}`); console.log(` Status: ${data.status}`); console.log(` Match: ${data.hashMatch}`); // "original" or "signed" if (data.completedAt) { console.log(` Completed: ${data.completedAt}`); } } else { console.log('❌ Document not found in inSigner records'); console.log(' The file may have been modified or is not from this organization'); }
return data;}
verifyDocument('./contract-signed.pdf');import hashlib
def verify_document(file_path): # Compute SHA-256 hash with open(file_path, "rb") as f: hash_value = hashlib.sha256(f.read()).hexdigest()
# Verify against inSigner res = insigner_request("POST", "/verify", json={"hash": hash_value}) data = res["data"]
if data["verified"]: print(f"✅ Document is authentic") print(f" Name: {data['documentName']}") print(f" Status: {data['status']}") print(f" Match: {data['hashMatch']}") # "original" or "signed" else: print("❌ Document not found in inSigner records")
return data
verify_document("./contract-signed.pdf")Understanding hash match types
Section titled “Understanding hash match types”The hashMatch field tells you which version of the document was matched:
| Value | Meaning |
|---|---|
"original" | The file matches the original PDF that was uploaded before signing |
"signed" | The file matches the completed signed PDF |
null | No match found |
Integration patterns
Section titled “Integration patterns”Automated compliance checks
Section titled “Automated compliance checks”// In your document processing pipelineasync function processUploadedDocument(filePath) { const result = await verifyDocument(filePath);
if (!result.verified) { throw new Error('Document failed verification'); }
if (result.status !== 'completed') { throw new Error(`Document is ${result.status}, not completed`); }
// Document is verified and fully signed — safe to process await archiveDocument(filePath, result);}Batch verification
Section titled “Batch verification”import { readdir } from 'fs/promises';import { join } from 'path';
async function verifyFolder(folderPath) { const files = await readdir(folderPath); const pdfs = files.filter(f => f.endsWith('.pdf'));
const results = await Promise.all( pdfs.map(async (file) => { const result = await verifyDocument(join(folderPath, file)); return { file, ...result }; }) );
const verified = results.filter(r => r.verified); const failed = results.filter(r => !r.verified);
console.log(`Verified: ${verified.length}/${results.length}`); if (failed.length > 0) { console.log('Failed files:', failed.map(r => r.file)); }}