Error Reference

Complete error code reference for VeriPlus API including status codes, error types, and troubleshooting guides.

Error Reference

Complete reference for all VeriPlus API errors including HTTP status codes, error codes, descriptions, and solutions.

Error Response Format

All API errors follow a consistent structure:

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_CREDITS",
    "message": "Not enough credits to perform this operation",
    "details": {
      "required": 2,
      "available": 0
    }
  },
  "meta": {
    "timestamp": "2024-01-15T10:30:00Z",
    "requestId": "req_xyz789"
  }
}

Fields:

  • success: Always false for errors
  • error.code: Machine-readable error code
  • error.message: Human-readable description
  • error.details: Additional context (optional)
  • meta.requestId: For support requests

HTTP Status Codes

Status CodeMeaningWhen Used
200OKSuccessful request
400Bad RequestInvalid input
401UnauthorisedMissing/invalid API key
402Payment RequiredInsufficient credits
403ForbiddenPermission denied
404Not FoundResource doesn't exist
409ConflictDuplicate resource
410GoneResource expired
413Payload Too LargeFile too large
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error
503Service UnavailableTemporary outage

Authentication Errors (401)

MISSING_API_KEY

Message: No Authorization header provided

Cause: API key not included in request

Solution:

// ❌ Wrong - no Authorization header
const response = await fetch('https://api.veriplus.co.uk/api/v3/applicants');
 
// ✅ Correct
const response = await fetch('https://api.veriplus.co.uk/api/v3/applicants', {
  headers: {
    'Authorization': `Bearer ${apiKey}`
  }
});

INVALID_API_KEY

Message: The provided API key is invalid or has been revoked

Cause:

  • API key typo or truncated
  • API key revoked
  • Wrong environment (test key in production)

Solution:

  1. Verify API key from dashboard
  2. Check environment variables
  3. Generate new API key if needed

EXPIRED_API_KEY

Message: API key has been revoked

Cause: API key manually revoked in dashboard

Solution: Generate new API key

Permission Errors (403)

INSUFFICIENT_PERMISSIONS

Message: API key lacks required permissions

Cause: API key doesn't have access to requested resource/action

Solution: Contact support to upgrade API key permissions (Enterprise feature)

FEATURE_NOT_AVAILABLE

Message: Feature not included in your plan

Cause: Attempting to use feature not in subscription plan

Example:

{
  "error": {
    "code": "FEATURE_NOT_AVAILABLE",
    "message": "Ongoing monitoring is not available on your plan",
    "details": {
      "feature": "aml_monitoring",
      "requiredPlan": "PROFESSIONAL",
      "currentPlan": "BASIC"
    }
  }
}

Solution: Upgrade subscription plan or contact sales

Credit Errors (402)

INSUFFICIENT_CREDITS

Message: Not enough credits to perform this operation

Cause: Credit balance too low

Example:

{
  "error": {
    "code": "INSUFFICIENT_CREDITS",
    "message": "Not enough credits to perform this operation",
    "details": {
      "required": 2,
      "available": 0
    }
  }
}

Solution:

// Check credit balance before operations
const balanceRes = await fetch('https://api.veriplus.co.uk/api/v3/credits/balance', {
  headers: { 'Authorization': `Bearer ${apiKey}` }
});
 
const balance = await balanceRes.json();
 
if (balance.data.available < 10) {
  // Alert user or purchase credits
  console.warn('Low credit balance:', balance.data.available);
}

Purchase credits:

  • Dashboard → Billing → Purchase Credits
  • Set up auto-recharge to prevent interruptions

Validation Errors (400)

INVALID_EMAIL

Message: Email format invalid

Cause: Email doesn't match format

Solution: Provide valid email address

INVALID_DATE_OF_BIRTH

Message: Date of birth format invalid

Cause: Date not in YYYY-MM-DD format

Solution:

// ❌ Wrong
dateOfBirth: '15/01/1990'
dateOfBirth: '01-15-1990'
 
// ✅ Correct
dateOfBirth: '1990-01-15'  // YYYY-MM-DD

INVALID_COUNTRY_CODE

Message: Unknown country code

Cause: Country code not ISO 3166-1 alpha-2

Solution:

// ❌ Wrong
country: 'UK'
country: 'USA'
country: 'GBR'
 
// ✅ Correct
country: 'GB'  // United Kingdom
country: 'US'  // United States

MISSING_REQUIRED_FIELD

Message: Required field missing

Example:

{
  "error": {
    "code": "MISSING_REQUIRED_FIELD",
    "message": "Required field 'firstName' is missing",
    "details": {
      "field": "firstName"
    }
  }
}

Solution: Provide all required fields

INVALID_FILE_FORMAT

Message: Unsupported file format

Cause: File format not supported

Supported Formats:

  • Images: JPEG, PNG, WebP
  • Videos: MP4, MOV, WebM
  • Audio: MP3, WAV, M4A
  • Documents: PDF, JPEG, PNG

Solution:

// Check file extension before upload
const allowedExtensions = ['.jpg', '.jpeg', '.png', '.webp'];
const fileExt = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
 
if (!allowedExtensions.includes(fileExt)) {
  console.error('Unsupported file format');
}

FILE_TOO_LARGE

Message: File exceeds size limit

Cause: File larger than allowed

Size Limits:

  • Images: 10 MB
  • Videos: 50 MB
  • Audio: 10 MB
  • Documents: 10 MB

Solution:

const maxSize = 10 * 1024 * 1024; // 10 MB
 
if (file.size > maxSize) {
  console.error('File too large. Max size: 10 MB');
  // Compress or resize file
}

Resource Errors

APPLICANT_NOT_FOUND (404)

Message: Applicant ID doesn't exist

Cause: Invalid applicant ID or applicant deleted

Solution: Verify applicant ID exists

VERIFICATION_NOT_FOUND (404)

Message: Verification ID doesn't exist

Cause: Invalid verification ID

Solution: Check verification ID in your records

VERIFICATION_EXPIRED (410)

Message: Upload URL has expired

Cause: Verification upload URL expired (1 hour lifetime)

Solution:

// Create new verification
const response = await fetch('https://api.veriplus.co.uk/api/v3/verifications', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    applicantId: applicantId,
    profileType: 'STANDARD'
  })
});

Duplicate Errors (409)

DUPLICATE_APPLICANT

Message: An applicant with this email already exists

Example:

{
  "error": {
    "code": "DUPLICATE_APPLICANT",
    "message": "An applicant with this email already exists",
    "details": {
      "existingApplicantId": "app_existing123"
    }
  }
}

Solution:

// Use existing applicant
const existingId = error.details.existingApplicantId;
 
// Or update existing applicant
await fetch(`https://api.veriplus.co.uk/api/v3/applicants/${existingId}`, {
  method: 'PATCH',
  body: JSON.stringify(updates)
});

DUPLICATE_VERIFICATION

Message: Active verification already exists for this applicant

Cause: Verification in progress for applicant

Solution: Wait for existing verification to complete or use existing verification ID

MONITORING_ALREADY_ACTIVE

Message: Monitoring already enabled for this applicant/wallet

Cause: Attempting to enable monitoring that's already active

Solution: Use existing monitoring ID

Rate Limit Errors (429)

RATE_LIMIT_EXCEEDED

Message: Too many requests, please slow down

Cause: Exceeded rate limit for your plan

Rate Limits:

  • FREE: 10 req/min
  • BASIC: 30 req/min
  • PROFESSIONAL: 100 req/min
  • ENTERPRISE: Custom

Solution - Exponential Backoff:

async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);
 
    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
      console.log(`Rate limited. Retrying in ${retryAfter}s...`);
 
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }
 
    return response;
  }
 
  throw new Error('Max retries exceeded');
}

Headers in Response:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1642251600
Retry-After: 60

Processing Errors (500)

ANALYSIS_FAILED

Message: Technical failure during analysis

Cause: Internal processing error

Solution:

  1. Retry the operation
  2. If persistent, contact support with requestId

EXTERNAL_SERVICE_ERROR

Message: External service temporarily unavailable

Cause: Upstream service (verification provider, blockchain) unavailable

Solution: Retry after a few minutes

NO_FACE_DETECTED

Message: No face found in image/video

Cause: Face detector couldn't find a face

Solution:

  • Ensure face is visible and well-lit
  • Face should be at least 200x200 pixels
  • Avoid extreme angles or obstructions

Service Errors (503)

SERVICE_UNAVAILABLE

Message: Service temporarily unavailable

Cause: Scheduled maintenance or temporary outage

Solution:

Error Handling Best Practices

1. Handle All Error Types

async function createApplicant(data) {
  try {
    const response = await fetch('https://api.veriplus.co.uk/api/v3/applicants', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });
 
    const result = await response.json();
 
    if (!response.ok) {
      switch (result.error.code) {
        case 'DUPLICATE_APPLICANT':
          // Use existing applicant
          return { applicantId: result.error.details.existingApplicantId };
 
        case 'INSUFFICIENT_CREDITS':
          // Alert user to purchase credits
          throw new Error('Please purchase credits to continue');
 
        case 'INVALID_EMAIL':
          // Ask user to correct email
          throw new Error('Please provide a valid email address');
 
        default:
          throw new Error(result.error.message);
      }
    }
 
    return result.data;
  } catch (error) {
    console.error('Failed to create applicant:', error);
    throw error;
  }
}

2. Log Request IDs

if (!response.ok) {
  const error = await response.json();
  console.error('Error:', error.error.code);
  console.error('Request ID:', error.meta.requestId); // For support
}

3. Implement Retry Logic

const RETRYABLE_CODES = [500, 503];
 
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
 
      if (response.ok) {
        return response;
      }
 
      if (!RETRYABLE_CODES.includes(response.status)) {
        // Don't retry client errors (4xx)
        return response;
      }
 
      // Retry server errors (5xx)
      const delay = Math.pow(2, i) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
 
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}

4. Graceful Degradation

try {
  await performDeepfakeScan(image);
} catch (error) {
  if (error.code === 'FEATURE_NOT_AVAILABLE') {
    // Feature not in plan - proceed without deepfake scan
    console.warn('Deepfake detection unavailable');
  } else {
    throw error;
  }
}

Getting Help

Error not listed here?

Contact support with:

  • Error code
  • Request ID (meta.requestId)
  • Full error response
  • Timestamp of occurrence

Support Channels:

Next Steps

Ready to integrate?

Get your API key and start building in minutes.

Ready to get started?

Start with our free plan. No credit card required.

We value your privacy

We use cookies to enhance your browsing experience, serve personalized content, and analyze our traffic. By clicking "Accept All", you consent to our use of cookies. Read our Privacy Policy and Cookie Policy for more information.