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.