Verda API Documentation

Verda offers a suite of powerful APIs for integrating professional credential verification and candidate assessment into your platform. This documentation covers our core APIs:

Apply API

Access verified professional credentials and work history for candidates in your system.

Free
Assess API

Evaluate candidates against job requirements with AI-powered analysis and ranking.

Paid
Report API

Report and access professional conduct history and create a trusted reputation system.

Free

Authentication Methods: Our APIs use different authentication methods based on their business model:

  • Apply API: Uses OAuth client credentials (client ID/secret) and is free to use. Register as a developer in the Developer Portal to receive your client ID and secret.
  • Report API: Uses OAuth client credentials (client ID/secret) and is free to use. Register as a developer in the Developer Portal to receive your client ID and secret.
  • Assess API: Uses API key authentication and is part of Verda's paid services. Employers can generate API keys from the Employer Dashboard.

Authentication

Verda APIs use two different authentication methods:

OAuth Client Authentication

Used by Apply API and Report API (free services)

Register in the Developer Portal to receive your credentials

API Key Authentication

Used by Assess API (paid service)

Generated in the Employer Dashboard

OAuth Client Authentication

The Apply API and Report API use OAuth client authentication with client ID and secret via HTTP Basic Authentication:

Authorization: Basic {base64_encoded_client_id:client_secret}

The authentication process follows these steps:

  1. Encode your client ID and client secret as client_id:client_secret
  2. Base64 encode the string from step 1
  3. Add the encoded string to the Authorization header: Authorization: Basic {encoded_string}

How to obtain credentials: Register as a developer in the Developer Portal to receive your client ID and secret for the Apply API and Report API.

Important: Keep your client secret secure and never expose it in client-side code or public repositories.

Example (Python)

import base64
import requests

def create_auth_header(client_id, client_secret):
    # Combine client ID and secret
    auth_string = f"{client_id}:{client_secret}"
    
    # Base64 encode
    encoded_auth = base64.b64encode(auth_string.encode()).decode()
    
    # Create header
    headers = {
        'Authorization': f'Basic {encoded_auth}'
    }
    
    return headers

API Key Authentication

The Assess API uses API key authentication. Include your API key in the X-API-Key header:

X-API-Key: your_api_key_here

How to obtain credentials: Employers can generate API keys from the Employer Dashboard. API keys are tied to your subscription plan.

Important: Keep your API key secure and never expose it in client-side code or public repositories. API keys can be revoked and regenerated from your dashboard if compromised.

Example (Python)

import requests

def create_api_key_header(api_key):
    # Create header with API key
    headers = {
        'X-API-Key': api_key,
        'Content-Type': 'application/json'
    }
    
    return headers

Apply API Overview

The Apply API allows you to retrieve verified professional credentials for Verda users, enabling:

  • ATS systems to verify candidate credentials
  • HRMS platforms to validate work history
  • Recruiting platforms to access verified professional profiles

This API follows RESTful principles and returns data in JSON format. All endpoints require authentication using your client ID and secret.

Note: The Apply API is currently read-only, supporting GET operations to retrieve professional profiles by email address.

Apply with Verda Button

When integrating the Apply API, you are required to use our standardized "Apply with Verda" button to maintain consistent branding and user experience.

Button Preview
Implementation

Include the following resources in your HTML:

<link rel="stylesheet" href="https://api.verda.work/static/css/api_buttons.css">
<script src="https://api.verda.work/static/js/api_buttons.js"></script>

Add the button HTML:

<button class="verda-button verda-apply-button" id="apply-with-verda-btn" data-verda-api="apply">
  Apply with Verda
</button>

Add your click handler:

document.getElementById('apply-with-verda-btn').addEventListener('click', function() {
  // Redirect to your OAuth flow or application process
  window.location.href = 'https://api.verda.work/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=apply_api';
});

Important: Using the standardized "Apply with Verda" button is mandatory for all Apply API integrations. Our compliance monitoring system automatically detects and reports non-compliant button implementations. For complete button implementation guidelines, visit the Button Standards Demo page.

GET Get Professional Profile

Public

Retrieve a professional's verified credentials by email address. This endpoint returns the profile data including work experiences, education history, and verification statuses.

Endpoint

GET /api/v1/apply/profile?email={email}

Authentication

Authorization: Basic {base64_encoded_client_id:client_secret}

Parameters

Parameter Type Required Description
email string Yes Email address of the professional to look up

Response

For an existing user, the response will include their profile data:

{
  "status": "success",
  "profile": {
    "id": 123,
    "email": "user@example.com",
    "name": "User Name",
    "work_experiences": [
      {
        "id": 456,
        "company": "Company Name",
        "title": "Job Title",
        "start_date": "2025-01-01",
        "end_date": "2025-12-31",
        "description": "Job responsibilities...",
        "verification_status": "verified"
      }
    ],
    "education": [
      {
        "id": 789,
        "institution": "University Name",
        "degree": "Bachelor's Degree",
        "field_of_study": "Computer Science",
        "start_date": "2020-01-01",
        "end_date": "2024-12-31",
        "verification_status": "unverified"
      }
    ],
    "skills": [],
    "total_work_items": 5,
    "total_evidence": 3,
    "total_references": 2
  }
}

If no user is found with the provided email:

{
  "status": "not_found",
  "message": "No profile found for this email address."
}

Implementation Example

import requests
import base64

def get_profile_by_email(email):
    # API endpoint
    url = f'https://verda.work/api/v1/apply/profile?email={email}'
    
    # Authentication using client ID and secret
    client_id = 'YOUR_CLIENT_ID'
    client_secret = 'YOUR_CLIENT_SECRET'
    auth_string = f"{client_id}:{client_secret}"
    encoded_auth = base64.b64encode(auth_string.encode()).decode()
    
    # Request headers
    headers = {
        'Authorization': f'Basic {encoded_auth}'
    }
    
    # Make API request
    response = requests.get(url, headers=headers)
    
    return response.json()

Assess API Overview

The Assess API allows you to evaluate candidates against job requirements with AI-powered analysis, enabling:

  • ATS systems to automatically screen and rank candidates
  • Job boards to match candidates to relevant positions
  • Recruiting platforms to prioritize candidate outreach

This API uses machine learning to analyze resumes against job descriptions, generating detailed insights about candidate fit, relevant experience, and skill alignment.

Note: The Assess API requires an API key and is part of Verda's paid services. You can generate API keys from the Employer Dashboard. Usage is billed based on your subscription plan.

Key Features

Match Scoring

Detailed relevance scores between candidates and job requirements

Skill Analysis

Identification of matching skills between resume and job description

Async Processing

Batch processing capabilities for analyzing multiple candidates

Assess with Verda Button

When integrating the Assess API, you are required to use our standardized "Assess with Verda" button to maintain consistent branding and user experience.

Button Preview
Implementation

Include the following resources in your HTML:

<link rel="stylesheet" href="https://api.verda.work/static/css/api_buttons.css">
<script src="https://api.verda.work/static/js/api_buttons.js"></script>

Add the button HTML:

<button class="verda-button verda-assess-button" id="assess-with-verda-btn" data-verda-api="assess">
  Assess with Verda
</button>

Add your click handler:

document.getElementById('assess-with-verda-btn').addEventListener('click', function() {
  // Implement your assessment flow using the API key
  const apiKey = 'YOUR_API_KEY';
  
  // Example: Show a modal to collect candidate information
  showCandidateForm(function(candidateData) {
    // Process candidate against job description
    fetch('https://api.verda.work/api/v1/ats/process', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': apiKey
      },
      body: JSON.stringify({
        job: { /* job details */ },
        candidates: [candidateData],
        processing_options: { mode: 'async' }
      })
    })
    .then(response => response.json())
    .then(data => {
      // Handle the response
      console.log(data);
    });
  });
});

Important: Using the standardized "Assess with Verda" button is mandatory for all Assess API integrations. Our compliance monitoring system automatically detects and reports non-compliant button implementations. For complete button implementation guidelines, visit the Button Standards Demo page.

POST Process Candidates

Paid

Process one or more candidate resumes against a job description. This endpoint analyzes the candidate's qualifications and provides a detailed assessment of their fit for the role.

Endpoint

POST /api/v1/ats/process

Authentication

X-API-Key: your_api_key_here

Request Format

{
  "job": {
    "title": "Senior Software Engineer",
    "description": "Full job description text...",
    "external_id": "your-job-reference-id",
    "company": "Your Company Name"
  },
  "candidates": [
    {
      "name": "Candidate Name",
      "email": "candidate@example.com",
      "resume_text": "Full resume text...",
      "external_id": "your-candidate-reference-id"
    }
  ],
  "processing_options": {
    "mode": "async"  // or "sync"
  }
}

Parameters

Parameter Type Required Description
job.title string Yes Title of the job position
job.description string Yes Full text of the job description
job.external_id string Yes Your unique reference ID for this job
job.company string Yes Company name offering the position
candidates array Yes Array of candidate objects to evaluate
candidates[].name string Yes Candidate's full name
candidates[].email string Yes Candidate's email address
candidates[].resume_text string Yes Full text of the candidate's resume
candidates[].external_id string Yes Your unique reference ID for this candidate
processing_options.mode string No Processing mode: "async" (default) or "sync"

Processing Modes: The API supports two processing modes:

  • async (recommended): Returns immediately with a batch ID. Results must be retrieved by polling the status endpoint.
  • sync: Waits for processing to complete, which may take 15-20 seconds per candidate.

Response (Async Mode)

{
  "candidates": [],
  "job": {
    "candidate_count": 1,
    "company": "Test Company Inc.",
    "status": "active",
    "title": "Senior Software Engineer",
    "verda_id": 24
  },
  "processing": {
    "batch_id": "batch_0a96c1e79579",
    "estimated_completion_time": "2s",
    "mode": "async",
    "status": "processing",
    "status_url": "/api/v1/ats/status/batch_0a96c1e79579"
  },
  "request_id": "req_dac3181f"
}

Response (Sync Mode)

{
  "relevance_score": 85.5,
  "matching_skills": ["Python", "JavaScript", "AWS"],
  "experience_analysis": "The candidate has 5 years of relevant experience in software development, with a focus on backend systems and cloud architecture. Their experience leading development teams at ABC Company aligns well with the leadership aspect of this role.",
  "education_analysis": "The candidate has a Bachelor's degree in Computer Science, meeting the educational requirements for this position.",
  "skills_analysis": "The candidate demonstrates strong skills in Python, JavaScript, and cloud technologies (AWS), which directly match the job requirements. Their experience with microservices architecture is particularly relevant.",
  "overall_analysis": "Overall, this candidate shows strong alignment with the job requirements, particularly in technical skills and leadership experience. With 5+ years of relevant experience and a matching technical stack, they appear to be a good fit for the Senior Software Engineer position."
}

Implementation Example (Python)

import requests
import json
import time
from uuid import uuid4

def process_candidates(api_key, job_data, candidate_data, mode="async"):
    """
    Process candidates against a job using the Assess API
    
    Args:
        api_key: Your Verda API key
        job_data: Dictionary with job title, description, etc.
        candidate_data: List of dictionaries with candidate details
        mode: "async" or "sync" processing mode
    
    Returns:
        Response JSON from the API
    """
    # API endpoint
    url = 'https://verda.work/api/v1/ats/process'
    
    # Request headers
    headers = {
        'X-API-Key': api_key,
        'Content-Type': 'application/json'
    }
    
    # Request payload
    payload = {
        "job": job_data,
        "candidates": candidate_data,
        "processing_options": {
            "mode": mode
        }
    }
    
    # Make API request
    if mode == "async":
        timeout = 10  # seconds
    else:
        timeout = 30  # seconds per candidate
    
    response = requests.post(
        url,
        headers=headers,
        json=payload,
        timeout=timeout
    )
    
    # Handle async mode (check status)
    if mode == "async" and response.status_code == 202:
        data = response.json()
        batch_id = data['processing']['batch_id']
        status_url = data['processing']['status_url']
        
        print(f"Async process initiated. Batch ID: {batch_id}")
        print(f"Status URL: {status_url}")
        
        # You would implement status polling here
        
    return response.json()

GET Check Processing Status

Paid

Check the status of an asynchronous processing request and retrieve results when available.

Endpoint

GET /api/v1/ats/status/{batch_id}

Authentication

X-API-Key: your_api_key_here

Parameters

Parameter Type Required Description
batch_id string Yes The batch ID received from the process API

Response (Processing)

{
  "status": "processing",
  "batch_id": "batch_0a96c1e79579",
  "progress": {
    "total": 1,
    "completed": 0,
    "estimated_completion_time": "5s"
  }
}

Response (Completed)

{
  "status": "completed",
  "batch_id": "batch_0a96c1e79579",
  "results": [
    {
      "candidate_id": "test_candidate_123",
      "relevance_score": 85.5,
      "matching_skills": ["Python", "JavaScript", "AWS"],
      "experience_analysis": "The candidate has 5 years of relevant experience...",
      "education_analysis": "The candidate has a Bachelor's degree in Computer Science...",
      "skills_analysis": "The candidate demonstrates strong skills in Python...",
      "overall_analysis": "Overall, this candidate shows strong alignment..."
    }
  ]
}

Implementation Example (Python)

import requests
import time

def check_processing_status(api_key, batch_id, max_attempts=10, interval=3):
    """
    Check status of an async processing request
    
    Args:
        api_key: Your Verda API key
        batch_id: The batch ID from the process API
        max_attempts: Maximum number of polling attempts
        interval: Time between polling attempts (seconds)
    
    Returns:
        Final result data or None if processing timed out
    """
    # Base URL
    base_url = 'https://verda.work'
    
    # Request headers
    headers = {
        'X-API-Key': api_key,
        'Content-Type': 'application/json'
    }
    
    # Poll for results
    for attempt in range(max_attempts):
        # Make status request
        status_url = f"{base_url}/api/v1/ats/status/{batch_id}"
        response = requests.get(
            status_url,
            headers=headers,
            timeout=10
        )
        
        if response.status_code == 200:
            data = response.json()
            
            # Check if processing is complete
            if data['status'] == 'completed':
                return data['results']
            
            # If still processing, wait and try again
            print(f"Processing {data.get('progress', {}).get('completed', 0)}/{data.get('progress', {}).get('total', '?')}...")
            
        else:
            print(f"Error checking status: {response.status_code}")
        
        # Wait before next attempt
        time.sleep(interval)
    
    # If we reach here, processing took too long
    print("Processing timed out")
    return None

Best Practices

Status Polling Strategy:

  • Initial poll: Wait the estimated_completion_time from the process response
  • Subsequent polls: Use exponential backoff (increase interval between requests)
  • Include timeouts and max attempts to prevent indefinite waiting
  • Handle 429 (rate limit) errors appropriately

Report API Overview

The Report API enables HRMS and ATS systems to report and access information about professional conduct issues, creating a comprehensive professional reputation system. Key use cases include:

  • HRMS systems that need to report "no-show" candidates or notice period violations
  • ATS platforms that want to verify candidates' professional reputation before hiring
  • Job boards that want to provide professional conduct insights to employers
  • Background check services that need to include conduct history in their reports

This API follows RESTful principles and returns data in JSON format. All endpoints require authentication using your client ID and secret.

Note: The Report API is free to use, encouraging data collection and creating a professional conduct ecosystem.

Key Features

Shadow Profiles

Ability to create and manage profiles for professionals not yet on the platform

Verification Process

Automated and manual verification workflows for conduct reports

Two-way System

Both reporting and querying capabilities for a complete ecosystem

Authentication

The Report API uses OAuth client authentication with client ID and secret via HTTP Basic Authentication, just like the Apply API:

Authorization: Basic {base64_encoded_client_id:client_secret}

Report to Verda Button

When integrating the Report API, you are required to use our standardized "Report to Verda" button to maintain consistent branding and user experience.

Button Preview
Implementation

Include the following resources in your HTML:

<link rel="stylesheet" href="https://api.verda.work/static/css/api_buttons.css">
<script src="https://api.verda.work/static/js/api_buttons.js"></script>

Add the button HTML:

<button class="verda-button verda-report-button" id="report-to-verda-btn" data-verda-api="report">
  Report to Verda
</button>

Add your click handler:

document.getElementById('report-to-verda-btn').addEventListener('click', function() {
  // Show a form to collect report details
  showReportForm(function(reportData) {
    // Submit the report
    const clientId = 'YOUR_CLIENT_ID';
    const clientSecret = 'YOUR_CLIENT_SECRET';
    const auth = btoa(`${clientId}:${clientSecret}`);
    
    fetch('https://api.verda.work/api/v1/reports', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Basic ${auth}`
      },
      body: JSON.stringify(reportData)
    })
    .then(response => response.json())
    .then(data => {
      // Handle the response
      console.log(data);
    });
  });
});

Important: Using the standardized "Report to Verda" button is mandatory for all Report API integrations. Our compliance monitoring system automatically detects and reports non-compliant button implementations. For complete button implementation guidelines, visit the Button Standards Demo page.

POST Submit a Report

Public

Submit a professional conduct report for a candidate. This endpoint creates a report and links it to an existing professional or creates a shadow profile if the professional doesn't exist yet.

Endpoint

POST /api/v1/reports

Authentication

Authorization: Basic {base64_encoded_client_id:client_secret}

Request Body

{
  "professional": {
    "email": "candidate@example.com",
    "name": "John Doe"
  },
  "employer": {
    "name": "Example Company",
    "domain": "example.com",
    "website": "https://example.com"
  },
  "report_type": "no_show",
  "description": "Candidate accepted offer but did not show up on start date",
  "incident_date": "2025-04-01T00:00:00Z"
}

Parameters

Parameter Type Required Description
professional.email string Yes Email address of the professional being reported
professional.name string Yes Name of the professional being reported
employer.name string Yes Name of the employer submitting the report
employer.domain string Yes Domain of the employer (e.g., example.com)
employer.website string No Website URL of the employer
report_type string Yes Type of report (no_show, notice_period_violation, interview_misconduct, job_abandonment, resume_misrepresentation, other)
description string Yes Detailed description of the conduct issue
incident_date string (ISO 8601) Yes Date when the incident occurred

Response

On successful submission:

{
  "success": true,
  "message": "Report submitted successfully",
  "report": {
    "id": 123,
    "reference_number": "d22a7862-ec61-4621-bc57-f490e3d552f5",
    "status": "submitted",
    "submission_date": "2025-04-17T08:06:20.618704"
  },
  "professional": {
    "id": 456,
    "is_new_profile": false
  }
}

Error Responses

For invalid requests:

{
  "success": false,
  "error": "invalid_request",
  "error_description": "Email is required",
  "field_errors": {
    "professional.email": "This field is required"
  }
}

Implementation Example

import requests
import base64
import json
from datetime import datetime

def submit_report(professional_email, professional_name, report_type, description):
    # API endpoint
    url = 'https://verda.work/api/v1/reports'
    
    # Authentication using client ID and secret
    client_id = 'YOUR_CLIENT_ID'
    client_secret = 'YOUR_CLIENT_SECRET'
    auth_string = f"{client_id}:{client_secret}"
    encoded_auth = base64.b64encode(auth_string.encode()).decode()
    
    # Request headers
    headers = {
        'Authorization': f'Basic {encoded_auth}',
        'Content-Type': 'application/json'
    }
    
    # Request payload
    payload = {
        "professional": {
            "email": professional_email,
            "name": professional_name
        },
        "employer": {
            "name": "Example Company",
            "domain": "example.com",
            "website": "https://example.com"
        },
        "report_type": report_type,
        "description": description,
        "incident_date": datetime.utcnow().isoformat()
    }
    
    # Make API request
    response = requests.post(url, headers=headers, json=payload)
    
    return response.json()

GET Get Report Details

Public

Retrieve details about a specific report using its reference number.

Endpoint

GET /api/v1/reports/{reference_number}

Authentication

Authorization: Basic {base64_encoded_client_id:client_secret}

Parameters

Parameter Type Required Description
reference_number string Yes Unique reference number of the report

Response

{
  "success": true,
  "report": {
    "id": 1,
    "reference_number": "d22a7862-ec61-4621-bc57-f490e3d552f5",
    "report_type": "no_show",
    "description": "Candidate did not show up for their first day of work",
    "incident_date": "2025-04-15T10:00:00+00:00",
    "employer_domain": "example.com",
    "verification_status": "submitted",
    "reliability_score": 0.5,
    "created_at": "2025-04-15T13:46:54.255129+00:00",
    "updated_at": "2025-04-15T13:46:54.255129+00:00",
    "professional": {
      "id": 15,
      "email": "test@example.com",
      "name": "",
      "profile_status": "incomplete"
    }
  }
}

Error Responses

If the report is not found:

{
  "success": false,
  "error": "not_found",
  "error_description": "Report not found"
}

GET List Professional Reports

Public

Retrieve all reports associated with a specific professional.

Endpoint

GET /api/v1/professionals/{professional_id}/reports

Authentication

Authorization: Basic {base64_encoded_client_id:client_secret}

Parameters

Parameter Type Required Description
professional_id integer Yes ID of the professional

Response

{
  "success": true,
  "professional": {
    "id": 15,
    "email": "test@example.com",
    "name": "",
    "profile_status": "incomplete"
  },
  "reports": [
    {
      "id": 4,
      "reference_number": "497ef7d0-8fca-472d-bc8a-9a12d6f09ae9",
      "report_type": "no_show",
      "description": "Candidate accepted offer but did not show up on start date",
      "incident_date": "2025-04-15T15:47:54.923877+00:00",
      "employer_domain": "example.com",
      "verification_status": "submitted",
      "reliability_score": 0.5,
      "created_at": "2025-04-15T15:47:54.492640+00:00",
      "updated_at": "2025-04-15T15:47:54.492640+00:00"
    },
    {
      "id": 1,
      "reference_number": "d22a7862-ec61-4621-bc57-f490e3d552f5",
      "report_type": "no_show",
      "description": "Candidate did not show up for their first day of work",
      "incident_date": "2025-04-15T10:00:00+00:00",
      "employer_domain": "example.com",
      "verification_status": "submitted",
      "reliability_score": 0.5,
      "created_at": "2025-04-15T13:46:54.255129+00:00",
      "updated_at": "2025-04-15T13:46:54.255129+00:00"
    }
  ],
  "total_count": 2
}

Error Responses

If the professional is not found:

{
  "success": false,
  "error": "not_found",
  "error_description": "Professional not found"
}

Implementation Example

import requests
import base64

def get_professional_reports(professional_id):
    # API endpoint
    url = f'https://verda.work/api/v1/professionals/{professional_id}/reports'
    
    # Authentication using client ID and secret
    client_id = 'YOUR_CLIENT_ID'
    client_secret = 'YOUR_CLIENT_SECRET'
    auth_string = f"{client_id}:{client_secret}"
    encoded_auth = base64.b64encode(auth_string.encode()).decode()
    
    # Request headers
    headers = {
        'Authorization': f'Basic {encoded_auth}'
    }
    
    # Make API request
    response = requests.get(url, headers=headers)
    
    return response.json()

Rate Limits

To ensure the reliability and proper resource allocation for our services, we implement rate limits for all APIs:

Apply API Rate Limits

Plan Rate Limit
Standard 100 requests/minute
Professional 500 requests/minute
Enterprise Custom limits

Report API Rate Limits

Plan Rate Limit
Standard 120 requests/minute
Professional 600 requests/minute
Enterprise Custom limits

Assess API Rate Limits

Plan Process API Limit Status API Limit Processing Quota
Starter 20 requests/minute 60 requests/minute 100 candidates/month
Professional 50 requests/minute 120 requests/minute 500 candidates/month
Enterprise Custom limits Custom limits Custom quota

Rate Limit Headers: All API responses include the following headers to help you monitor your usage:

  • X-RateLimit-Limit: Maximum number of requests allowed per minute
  • X-RateLimit-Remaining: Number of requests remaining in the current window
  • X-RateLimit-Reset: Unix timestamp when the rate limit will reset

Processing Quota: The Assess API imposes both rate limits (requests per minute) and processing quotas (candidates processed per month). When you reach your monthly quota, the API will return a 402 (Payment Required) status code until your quota resets or your plan is upgraded.

Developer Support

Need help with integrating Verda APIs into your platform? Our developer support team is here to help.

Email Support

For technical questions or account-specific issues:

api-support@verda.work

Sample Code

Check out our GitHub repository for more code samples:

Verda API Examples

Additional Resources

API Guides

Comprehensive guides for implementing our APIs:

SDK Libraries

Client libraries for popular languages:

Test Environment

Sandbox environment for testing API integration:

Verda Sandbox

API keys available in your dashboard