Integration Guide
Advanced patterns for real-world applications
React / Next.js
"use client";
import { useEffect, useState } from 'react';
export default function VerifyForm() {
const [sessionId, setSessionId] = useState(null);
const [certUrl, setCertUrl] = useState(null);
useEffect(() => {
// Load SDK on mount
const script = document.createElement('script');
script.src = 'https://pulse.bp.la/v1/sdk.js';
script.onload = () => {
window.HumanPulse.init('textarea-id');
};
document.body.appendChild(script);
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
const result = await window.HumanPulse.finalize();
setCertUrl(result.certificateUrl);
// Send form with proof
await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify({
content: document.getElementById('textarea-id').value,
certificateUrl: result.certificateUrl
})
});
};
return (
<form onSubmit={handleSubmit}>
<textarea id="textarea-id" required />
<button type="submit">Submit with Human Proof</button>
</form>
);
}Vanilla JavaScript
// After including the SDK script
// Initialize on input element
document.addEventListener('DOMContentLoaded', () => {
window.HumanPulse.init('my-textarea');
});
// On form submit
document.getElementById('submit-btn').addEventListener('click', async () => {
const result = await window.HumanPulse.finalize();
if (result.certificateUrl) {
// Submit form with proof attached
const formData = new FormData(document.getElementById('my-form'));
formData.append('certificateUrl', result.certificateUrl);
await fetch('/api/verify', { method: 'POST', body: formData });
}
});Server-Side Verification
Verify the certificate on your backend:
// Node.js / Next.js API route
export async function POST(req) {
const { certificateUrl, content } = await req.json();
// Fetch and verify certificate
const certRes = await fetch(certificateUrl);
const cert = await certRes.json();
// Check if signature is valid and recent
const isValid = cert.signature && cert.manifest_hash;
const isRecent = Date.now() - cert.timestamp < 3600000; // 1 hour
if (!isValid || !isRecent) {
return Response.json({ error: 'Invalid proof' }, { status: 403 });
}
// Proceed with submission
return Response.json({ success: true, submissionId: generateId() });
}Subscribe to Keystroke Events
Listen to real-time keystroke events for advanced analytics:
// Listen to keystroke events
const unsubscribe = window.HumanPulse.onKeystroke((event) => {
console.log('Keystroke detected:', {
timestamp: event.timestamp,
latency: event.latency, // ms since last keystroke
delta_length: event.delta_length // character count change
});
// Update UI visualization, analytics, etc.
});
// Unsubscribe when done
unsubscribe();Bot Detection Strategy
Paste Injection
Large character additions (>50 chars) with minimal latency (<50ms) trigger instant flagging
delta_length > 50 && latency < 50Uniform Typing
Human typing has natural variation. Bots type at consistent speeds
Low IKI variance = suspiciousImpossibly Fast
Average human typing is 40-100 wpm. Sub-30ms keystrokes are impossible
mean(IKI) < 30msBest Practices
- ✓Always verify certificates server-side
- ✓Check certificate timestamp to prevent replay attacks
- ✓Store certificateUrl with submission for audit trails
- ✓Combine Pulse with rate limiting for defense-in-depth
- ✓Display visual feedback during finalization
- ✓Test with real users to calibrate thresholds
- ✓Log flagged sessions for analysis