VeroID

Best Practices

Recommendations for integrating VeroID

Security

Server-Side Only

Never call the VeroID API from client-side code:

// ✅ DO: Server-side API route
export async function POST(req) {
  const data = await req.json();
  const result = await fetch('https://api.veroid.com.au/v1/verify', {
    headers: { 'X-API-Key': process.env.VEROID_API_KEY },
    body: JSON.stringify(data),
  });
  return result.json();
}

Store Keys in Environment Variables

// ✅ DO: Use environment variables
const apiKey = process.env.VEROID_API_KEY;

// ❌ DON'T: Hardcode keys
const apiKey = 'sk_live_abc123...';

Error Handling

Implement Retries

Only S (system error) responses are transient and safe to retry. Y, N, and D are definitive outcomes — do not retry them.

async function verifyWithRetry(data, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const result = await verify(data);

    // Y, N, D are definitive — return immediately
    if (result.status !== 'error') return result;

    // S = system error at issuer or DVS Hub — safe to retry with backoff
    if (result.responseCode === 'S') {
      await sleep(1000 * Math.pow(2, attempt));
      continue;
    }

    return result;
  }
}

Handle All Outcomes

const result = await verify(data);

switch (result.responseCode) {
  case 'Y':
    // Data matches the issuer record
    break;
  case 'N':
    // Data does not match the issuer record
    break;
  case 'D':
    // Data error at the issuer (record not held at source)
    break;
  case 'S':
    // System error — may retry
    break;
}

Compliance

Data Handling

  • Don't store PII longer than necessary
  • Don't log sensitive document numbers
  • Do store verification IDs for audit trails
// ✅ DO: Log verification ID only
logger.info('Verification completed', { 
  verificationId: result.verificationId,
  status: result.status 
});

// ❌ DON'T: Log PII
logger.info('Verification', { 
  name: data.givenName,
  licenceNumber: data.licenceNumber 
});