Verafy API Best Practices Guide
Build robust, scalable, and user-friendly applications with the Verafy AI Swarm Explorer API.
Related resources: Full API Documentation | Use Cases | FAQs
🚀Getting Started
✅ Do:
- Store API keys securely using environment variables
- Implement key rotation strategies for production systems
- Use separate API keys for development, staging, and production
- Monitor API key usage and set up alerts for unusual activity
❌ Don't:
- Hard-code API keys in your source code
- Share API keys in public repositories
- Use production keys in development environments
- Ignore API key usage patterns and anomalies
Code Example:
// ✅ Good: Environment variable usage const apiKey = process.env.VERAFY_API_KEY; // ❌ Bad: Hard-coded API key const apiKey = "vfy_1234567890abcdef";
Default Limits: 100 requests per hour per API key
Best Practices:
- Implement client-side rate limiting to avoid hitting API limits
- Use exponential backoff for retry logic
- Cache results when appropriate to reduce API calls
- Monitor rate limit headers and adjust request frequency
Implementation Example:
class VerafyClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.lastRequestTime = 0;
this.minRequestInterval = 36000; // 36 seconds
}
async makeRequest(endpoint, data) {
const now = Date.now();
const timeSinceLastRequest = now - this.lastRequestTime;
if (timeSinceLastRequest < this.minRequestInterval) {
await new Promise(resolve =>
setTimeout(resolve, this.minRequestInterval - timeSinceLastRequest)
);
}
// Make request...
this.lastRequestTime = Date.now();
}
}⚡Performance Optimization
Multi-Level Caching:
- Cache validator lists, query results, and frequently accessed data
- Set appropriate TTL values: validator lists (1 hour), query results (24 hours)
- Benefit: Reduces API calls by 60-80% and improves response times
Cache Implementation:
class VerafyCache {
constructor() {
this.memoryCache = new Map();
this.TTL = {
validators: 3600000, // 1 hour
queries: 86400000, // 24 hours
};
}
async getValidators() {
const cached = this.memoryCache.get('validators');
if (cached && Date.now() - cached.timestamp < this.TTL.validators) {
return cached.data;
}
const validators = await this.fetchFromAPI('/validators/active');
this.memoryCache.set('validators', {
data: validators,
timestamp: Date.now()
});
return validators;
}
}Smart Retry Logic:
- Use exponential backoff with jitter for failed requests
- Implement circuit breaker pattern for unreliable services
- Benefit: Improves resilience and prevents cascading failures
Retry Handler Example:
class RetryHandler {
async withRetry(operation, maxRetries = 3) {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (attempt === maxRetries) break;
// Exponential backoff with jitter
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
const jitter = Math.random() * 1000;
await new Promise(resolve =>
setTimeout(resolve, delay + jitter)
);
}
}
throw lastError;
}
}🎨User Experience
Layered Information Architecture:
- Level 1: Simple verified/unverified status with confidence score
- Level 2: Validator consensus breakdown and key findings
- Level 3: Detailed validator responses and source references
- Level 4: Full technical details and methodology
React Implementation:
function FactCheckResult({ verification }) {
const [detailLevel, setDetailLevel] = useState(1);
return (
<div className="fact-check-result">
{/* Level 1: Basic Status */}
<Badge variant={verification.verified ? "success" : "warning"}>
{verification.verified ? "✓ Verified" : "⚠ Needs Review"}
</Badge>
<span className="confidence-score">
{Math.round(verification.confidence * 100)}% confidence
</span>
{/* Progressive detail levels */}
{detailLevel >= 2 && <ConsensusBreakdown />}
{detailLevel >= 3 && <ValidatorDetails />}
{detailLevel >= 4 && <TechnicalDetails />}
<button onClick={() => setDetailLevel(prev => prev + 1)}>
Show More Details
</button>
</div>
);
}WCAG 2.1 AA Compliance:
- Provide screen reader support for verification results
- Use high contrast colors for status indicators
- Ensure keyboard navigation for all interactive elements
- Benefit: Makes fact-checking accessible to all users
Accessible Component Example:
function AccessibleVerificationResult({ result }) {
const statusText = result.verified ?
`Verified with ${Math.round(result.confidence * 100)}% confidence` :
`Could not verify with ${Math.round(result.confidence * 100)}% confidence`;
return (
<div
role="region"
aria-label="Fact-check result"
aria-live="polite"
>
<div className="sr-only">
{statusText}. {result.validator_count} validators participated.
</div>
<button
onClick={() => showDetails()}
aria-expanded={showingDetails}
aria-controls="verification-details"
>
{showingDetails ? 'Hide' : 'Show'} verification details
</button>
</div>
);
}🔒Security & Privacy
Sensitive Information Handling:
- Remove PII before sending queries to validators
- Implement data masking for sensitive content
- Log only non-sensitive metadata
- Benefit: Ensures privacy compliance and data protection
Data Sanitization Function:
function sanitizeQuery(query) {
return query
.replace(/\b\d{3}-?\d{2}-?\d{4}\b/g, '[SSN]') // Social Security
.replace(/\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g, '[CARD]') // Credit cards
.replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[EMAIL]') // Email
.replace(/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g, '[PHONE]'); // Phone numbers
}Secure Implementation:
- Validate API key format before making requests
- Add security headers and request signing
- Implement request ID tracking for audit trails
- Benefit: Prevents unauthorized access and improves security posture
Secure Client Example:
class SecureVerafyClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.rateLimiter = new RateLimiter();
}
async makeRequest(endpoint, data) {
// Validate API key format
if (!this.validateApiKeyFormat(this.apiKey)) {
throw new Error('Invalid API key format');
}
// Add security headers
const headers = {
'X-API-Key': this.apiKey,
'Content-Type': 'application/json',
'User-Agent': 'MyApp/1.0',
'X-Request-ID': generateRequestId()
};
return fetch(endpoint, {
headers,
body: JSON.stringify(data)
});
}
}🏥Domain-Specific Examples
Article Verification Workflow:
- Extract and prioritize factual claims from articles
- Verify claims in parallel with context-aware processing
- Generate comprehensive article credibility scores
News Fact Checker Implementation:
class NewsFactChecker {
async verifyArticle(article) {
// Extract factual claims from article
const claims = this.extractClaims(article.content);
// Prioritize claims by importance
const prioritizedClaims = claims
.sort((a, b) => this.calculateImportance(b) - this.calculateImportance(a))
.slice(0, 10); // Limit to top 10 claims
// Verify claims in parallel
const verifications = await Promise.allSettled(
prioritizedClaims.map(claim =>
this.verafyClient.broadcastQuery({
query: claim.text,
context: {
domain: 'journalism',
urgency: article.breaking ? 'high' : 'normal',
source_credibility: article.source.rating
}
})
)
);
return this.aggregateVerifications(verifications);
}
}Medical Claim Verification:
- Enhanced validation for healthcare claims
- Cross-reference with medical databases
- Regulatory compliance checks (FDA, CDC, WHO)
- Include medical disclaimers for user safety
Health Fact Checker Example:
class HealthFactChecker {
async verifyMedicalClaim(claim) {
// Healthcare claims require extra validation
const verification = await this.verafyClient.broadcastQuery({
query: claim,
context: {
domain: 'healthcare',
sensitivity: 'high',
evidence_standard: 'peer_reviewed',
regulatory_compliance: ['FDA', 'CDC', 'WHO']
},
selectedLLMIds: this.getMedicalValidators()
});
// Cross-reference with medical databases
const crossReferences = await this.crossReferenceWithMedicalDB(claim);
return {
...verification,
medical_consensus: crossReferences.consensus,
evidence_quality: crossReferences.evidence_grade,
disclaimer: 'This verification is for informational purposes only. Consult healthcare professionals for medical advice.'
};
}
}🧪Testing Strategies
Key Testing Areas:
- Rate limiting behavior and error handling
- Cache effectiveness and TTL expiration
- API response parsing and validation
- Security measures and input sanitization
Unit Test Example:
describe('VerafyClient', () => {
let client;
beforeEach(() => {
client = new VerafyClient('test-api-key');
});
it('should handle rate limiting gracefully', async () => {
// Mock rate limit response
jest.spyOn(global, 'fetch').mockResolvedValueOnce({
ok: false,
status: 429,
headers: new Headers({ 'retry-after': '60' })
});
const result = await client.broadcastQuery('test query');
expect(result.error).toBe(true);
expect(result.retryAfter).toBe(60);
});
it('should cache validator results', async () => {
const validators = await client.getValidators();
const cachedValidators = await client.getValidators();
expect(validators).toEqual(cachedValidators);
expect(fetch).toHaveBeenCalledTimes(1);
});
});End-to-End Testing:
- Verify known true and false statements
- Test controversial claims handling
- Validate consensus scoring accuracy
- Check source reference quality
Integration Test Example:
describe('End-to-End Fact Checking', () => {
it('should verify a known true statement', async () => {
const client = new VerafyClient(process.env.TEST_API_KEY);
const result = await client.broadcastQuery('The Earth orbits the Sun');
expect(result.verified).toBe(true);
expect(result.confidence).toBeGreaterThan(0.9);
expect(result.validator_count).toBeGreaterThan(3);
});
it('should handle controversial claims appropriately', async () => {
const client = new VerafyClient(process.env.TEST_API_KEY);
const result = await client.broadcastQuery('Climate change is caused by human activities');
expect(result.confidence).toBeGreaterThan(0.7);
expect(result.consensus_details).toBeDefined();
expect(result.source_references).toHaveLength.greaterThan(0);
});
});Ready to Build?
These best practices will help you build production-ready applications with the Verafy API. Start with the basics and gradually implement advanced patterns as your application grows.
Need Help? Contact @csjcode on Telegram for technical support and credit top-ups
This guide is regularly updated to reflect API improvements and community feedback.