Skip to main content

Webhook Events

Theary delivers webhook events to notify your application about verification status changes. This document provides exhaustive documentation of all event types, payload structures, and field definitions.

Payload Structure

All webhook events follow this structure:
{
  "event": "<WebhookEventType>",
  "occurredAt": "<ISO 8601 timestamp>",
  "data": {
    /* Event-specific payload */
  }
}

Top-Level Fields

FieldTypeRequiredDescription
eventWebhookEventTypeYesEvent type identifier. One of: verification.completed, verification.action_required, verification.notification
occurredAtstring (ISO 8601)YesTimestamp when the event was generated
dataobjectYesEvent-specific payload. Structure varies by event type

WebhookEventType Enum

ValueDescription
verification.completedVerification search completed with results
verification.action_requiredVerification requires manual intervention
verification.notificationIntermediate notification during verification process

HTTP Headers

Every webhook request includes these headers:
HeaderTypeDescription
Content-TypestringAlways application/json
X-Event-TypeWebhookEventTypeEvent type (e.g., verification.completed)
X-Event-Idstring (UUID)Unique delivery identifier for idempotency
X-Search-TypeSearchTypeSearch type when available (e.g., EMPLOYMENT)
X-External-Search-IdstringExternal identifier provided at order creation
X-Endpoint-SourcestringRouting source: type-specific or fallback
User-AgentstringAlways Theary-Webhook-Delivery/1.0
AuthorizationstringBasic auth header when configured (format: Basic <base64>)
X-Webhook-SignaturestringHMAC-SHA256 signature when secret is configured

Signature Verification

Webhooks are signed using HMAC-SHA256. The signature is provided in the X-Webhook-Signature header with format sha256=<hex>.
const crypto = require('crypto')

function verifyWebhookSignature(rawBody, signature, secret) {
  const signatureValue = signature.replace('sha256=', '')
  const expectedSignature = crypto.createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex')

  return crypto.timingSafeEqual(Buffer.from(signatureValue, 'hex'), Buffer.from(expectedSignature, 'hex'))
}
Important: Always verify using the raw request body bytes, not parsed JSON.

Common Enums

SearchType

ValueDescription
EMPLOYMENTEmployment verification
EDUCATIONEducation/credential verification
CRIMINALCriminal background check
REFERENCEProfessional reference check

VerificationChannel

ValueDescription
EMAILEmail communication channel
VOICEPhone/voice communication channel
FAXFax communication channel

StandardOutcomeCode

ValueTerminalDescription
VERIFIEDYesInformation successfully verified
NO_RECORDYesNo record found for the subject
THIRD_PARTYYesRequires third-party vendor completion
WRONG_ORGYesRequest misdirected to wrong organization
INFO_REQUESTEDNoAdditional information requested
INSUFFICIENTNoInsufficient information to proceed
RECEIVEDNoRequest received, processing
STARTEDNoVerification process started
SENTNoOutbound communication sent
FAILEDNoAttempt failed (retryable)
SUPPRESSEDNoCommunication suppressed

Event: verification.completed

Sent when a verification search completes with results.

Data Fields

FieldTypeRequiredDescription
searchIdstring (UUID)YesUnique search identifier
verificationIdstring (UUID)YesVerification result identifier
externalSearchIdstringNoExternal identifier from order creation
searchTypeSearchTypeNoType of verification performed
statusstringNoHuman-readable status (e.g., QA Review, Completed)
channelVerificationChannelNoTerminal channel that completed the verification
verificationResultVerificationResultYesComplete verification result object
accreditationAccreditationResultNoAccreditation data (education searches only)

VerificationResult Object

FieldTypeRequiredDescription
idstring (UUID)YesVerification result primary key
searchIdstring (UUID)YesAssociated search ID
outcomeStandardOutcomeCodeYesVerification outcome
resultDetailsstring or objectNoRaw extraction data (JSON)
extractedDataobjectNoParsed extraction data
submittedAtstring (ISO 8601)NoWhen result was submitted
createdAtstring (ISO 8601)NoRecord creation timestamp
updatedAtstring (ISO 8601)NoRecord update timestamp
channelVerificationChannelNoChannel that produced the result
additionalCommentsstringNoFree-form notes from verification
discrepancybooleanNoTrue if verified data differs from provided data
employmentVerificationEmploymentVerificationConditionalPresent for EMPLOYMENT searches
educationVerificationEducationVerificationConditionalPresent for EDUCATION searches
verifierVerifierProfileNoVerifier contact information

VerifierProfile Object

FieldTypeRequiredDescription
firstNamestringNoVerifier’s first name
lastNamestringNoVerifier’s last name
positionstringNoVerifier’s job title or role

EmploymentVerification Object

Complete employment verification data with provided (claimed) and verified fields.

Provided Fields (from applicant/requester)

FieldTypeDescription
providedCompanyNamestringClaimed employer name
providedContactNamestringContact name provided
providedContactNumberstringContact phone provided
providedContactEmailstringContact email provided
providedLocationstringEmployer location
providedStartDatestring (YYYY-MM-DD)Claimed employment start date
providedEndDatestring (YYYY-MM-DD)Claimed employment end date
providedPositionstringClaimed job title
providedSalarystringClaimed compensation
providedAddress1stringEmployer address line 1
providedAddress2stringEmployer address line 2
providedCitystringEmployer city
providedStatestringEmployer state
providedZipstringEmployer postal code

Verified Fields (from verification)

FieldTypeDescription
verifiedEntityIdstringInternal employer entity ID
verifiedCompanyNamestringConfirmed employer name
verifiedContactNamestringName of person who verified
verifiedContactNumberstringVerified contact phone
verifiedContactEmailstringVerified contact email
verifiedLocationstringConfirmed employer location
verifiedPositionstringConfirmed job title
verifiedSalarystringConfirmed compensation
verifiedContactIdstringInternal contact entity ID
verifiedStartDatestring (YYYY-MM-DD)Confirmed start date
verifiedEndDatestring (YYYY-MM-DD)Confirmed end date
verifiedReasonLeftstringReason for leaving employment
verifiedRehireboolean or nullRehire eligibility
commentsstringAdditional verifier comments
doNotContactbooleanDo-not-contact flag from request
verifierFirstNamestringVerifier first name
verifierLastNamestringVerifier last name
verifierPositionstringVerifier job title

Example: Employment Verification (Email)

{
  "event": "verification.completed",
  "occurredAt": "2025-12-02T15:30:00.000Z",
  "data": {
    "searchId": "550e8400-e29b-41d4-a716-446655440000",
    "verificationId": "660e8400-e29b-41d4-a716-446655440000",
    "externalSearchId": "candidate-123",
    "searchType": "EMPLOYMENT",
    "status": "Completed",
    "channel": "EMAIL",
    "verificationResult": {
      "id": "770e8400-e29b-41d4-a716-446655440000",
      "searchId": "550e8400-e29b-41d4-a716-446655440000",
      "outcome": "VERIFIED",
      "submittedAt": "2025-12-02T15:30:00.000Z",
      "createdAt": "2025-12-02T14:00:00.000Z",
      "updatedAt": "2025-12-02T15:30:00.000Z",
      "channel": "EMAIL",
      "additionalComments": "Verification completed via email response",
      "discrepancy": false,
      "extractedData": {
        "employmentVerified": true,
        "employerName": "Acme Corporation",
        "jobTitle": "Software Engineer",
        "startDate": "2020-01-15",
        "endDate": "2023-12-31",
        "rehireEligibility": "Yes, eligible for rehire",
        "reasonForLeaving": "Accepted position at another company",
        "confidence": 0.95
      },
      "employmentVerification": {
        "providedCompanyName": "Acme Corporation",
        "providedPosition": "Software Engineer",
        "providedStartDate": "2020-01-15",
        "providedEndDate": "2023-12-31",
        "providedContactName": null,
        "providedContactNumber": null,
        "providedContactEmail": null,
        "providedLocation": "San Francisco, CA",
        "providedSalary": null,
        "providedAddress1": null,
        "providedAddress2": null,
        "providedCity": "San Francisco",
        "providedState": "CA",
        "providedZip": null,
        "verifiedEntityId": null,
        "verifiedCompanyName": "Acme Corporation",
        "verifiedContactName": "Marcia Harris",
        "verifiedContactNumber": "+14155551234",
        "verifiedContactEmail": "[email protected]",
        "verifiedLocation": "San Francisco, CA",
        "verifiedPosition": "Software Engineer",
        "verifiedSalary": "$145,000/year",
        "verifiedContactId": null,
        "verifiedStartDate": "2020-01-15",
        "verifiedEndDate": "2023-12-31",
        "verifiedReasonLeft": "Accepted position at another company",
        "verifiedRehire": true,
        "comments": "Employee left in good standing",
        "doNotContact": false,
        "verifierFirstName": "Marcia",
        "verifierLastName": "Harris",
        "verifierPosition": "HR Manager"
      },
      "verifier": {
        "firstName": "Marcia",
        "lastName": "Harris",
        "position": "HR Manager"
      }
    }
  }
}

Example: Employment Verification (Voice)

{
  "event": "verification.completed",
  "occurredAt": "2025-12-02T11:45:00.000Z",
  "data": {
    "searchId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "verificationId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "externalSearchId": "emp-verify-456",
    "searchType": "EMPLOYMENT",
    "status": "Completed",
    "channel": "VOICE",
    "verificationResult": {
      "id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
      "searchId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "outcome": "VERIFIED",
      "submittedAt": "2025-12-02T11:45:00.000Z",
      "createdAt": "2025-12-02T11:30:00.000Z",
      "updatedAt": "2025-12-02T11:45:00.000Z",
      "channel": "VOICE",
      "additionalComments": "Verified via phone call with HR department",
      "discrepancy": true,
      "extractedData": {
        "employmentVerified": true,
        "employerName": "Tech Solutions Inc",
        "jobTitle": "Senior Developer",
        "startDate": "2019-03-01",
        "endDate": "2024-06-15",
        "confidence": 0.92
      },
      "employmentVerification": {
        "providedCompanyName": "Tech Solutions",
        "providedPosition": "Developer",
        "providedStartDate": "2019-03-15",
        "providedEndDate": "2024-06-30",
        "providedContactName": null,
        "providedContactNumber": "+18005551234",
        "providedContactEmail": null,
        "providedLocation": "Austin, TX",
        "providedSalary": null,
        "providedAddress1": null,
        "providedAddress2": null,
        "providedCity": "Austin",
        "providedState": "TX",
        "providedZip": null,
        "verifiedEntityId": null,
        "verifiedCompanyName": "Tech Solutions Inc",
        "verifiedContactName": "James Wilson",
        "verifiedContactNumber": "+15125559876",
        "verifiedContactEmail": null,
        "verifiedLocation": "Austin, TX",
        "verifiedPosition": "Senior Developer",
        "verifiedSalary": null,
        "verifiedContactId": null,
        "verifiedStartDate": "2019-03-01",
        "verifiedEndDate": "2024-06-15",
        "verifiedReasonLeft": null,
        "verifiedRehire": null,
        "comments": "Title was Senior Developer, not Developer. Start date was March 1, not March 15.",
        "doNotContact": false,
        "verifierFirstName": "James",
        "verifierLastName": "Wilson",
        "verifierPosition": "HR Coordinator"
      },
      "verifier": {
        "firstName": "James",
        "lastName": "Wilson",
        "position": "HR Coordinator"
      }
    }
  }
}

EducationVerification Object

Complete education verification data with provided and verified fields.

Provided Fields

FieldTypeDescription
providedSchoolNamestringClaimed institution name
providedLocationstringInstitution location
providedAddress1stringAddress line 1
providedAddress2stringAddress line 2
providedCitystringCity
providedStatestringState
providedZipstringPostal code
providedContactNamestringContact name
providedContactNumberstringContact phone
providedContactEmailstringContact email
providedDegreestringClaimed degree
providedMajorstringClaimed major
providedMinorstringClaimed minor
providedStartDatestring (YYYY-MM-DD)Attendance start date
providedEndDatestring (YYYY-MM-DD)Attendance end date
providedGraduatedstringGraduation status claimed
providedGraduationDatestring (YYYY-MM-DD)Claimed graduation date

Verified Fields

FieldTypeDescription
verifiedEntityIdstringInternal institution entity ID
verifiedSchoolNamestringConfirmed institution name
verifiedLocationstringConfirmed location
verifiedDegreestringConfirmed degree
verifiedMajorstringConfirmed major
verifiedMinorstringConfirmed minor
verifiedGpastringConfirmed GPA
verifiedStartDatestring (YYYY-MM-DD)Confirmed start date
verifiedEndDatestring (YYYY-MM-DD)Confirmed end date
verifiedGraduatedstringConfirmed graduation status
verifiedGraduationDatestring (YYYY-MM-DD)Confirmed graduation date
verifiedContactNamestringRegistrar/contact name
verifiedContactNumberstringContact phone
verifiedContactEmailstringContact email
commentsstringAdditional comments
verifierFirstNamestringVerifier first name
verifierLastNamestringVerifier last name
verifierPositionstringVerifier title

Example: Education Verification (Fax)

{
  "event": "verification.completed",
  "occurredAt": "2025-12-02T16:45:00.000Z",
  "data": {
    "searchId": "ed9a2f9e-0bf5-4aa2-ac7a-9f4c42355940",
    "verificationId": "vr_f1c64c38-6403-49c9-91af-127c7fcb8f4c",
    "externalSearchId": "edu-verify-880",
    "searchType": "EDUCATION",
    "status": "Completed",
    "channel": "FAX",
    "verificationResult": {
      "id": "vr_f1c64c38-6403-49c9-91af-127c7fcb8f4c",
      "searchId": "ed9a2f9e-0bf5-4aa2-ac7a-9f4c42355940",
      "outcome": "VERIFIED",
      "submittedAt": "2025-12-02T16:45:00.000Z",
      "createdAt": "2025-11-28T09:12:44.000Z",
      "updatedAt": "2025-12-02T16:45:00.000Z",
      "channel": "FAX",
      "additionalComments": "Sealed transcript received via fax",
      "discrepancy": false,
      "extractedData": {
        "educationVerified": true,
        "institutionName": "Stanford University",
        "qualification": "Bachelor of Science",
        "fieldOfStudy": "Computer Science",
        "graduationDate": "2022-06-12",
        "gpa": "3.84/4.0",
        "confidence": 0.97
      },
      "educationVerification": {
        "providedSchoolName": "Stanford University",
        "providedLocation": "Stanford, CA",
        "providedAddress1": null,
        "providedAddress2": null,
        "providedCity": "Stanford",
        "providedState": "CA",
        "providedZip": "94305",
        "providedContactName": null,
        "providedContactNumber": null,
        "providedContactEmail": null,
        "providedDegree": "BS Computer Science",
        "providedMajor": "Computer Science",
        "providedMinor": null,
        "providedStartDate": "2018-09-01",
        "providedEndDate": "2022-06-15",
        "providedGraduated": "Yes",
        "providedGraduationDate": "2022-06-15",
        "verifiedEntityId": null,
        "verifiedSchoolName": "Stanford University",
        "verifiedLocation": "Stanford, CA",
        "verifiedDegree": "Bachelor of Science",
        "verifiedMajor": "Computer Science",
        "verifiedMinor": null,
        "verifiedGpa": "3.84/4.0",
        "verifiedStartDate": "2018-09-01",
        "verifiedEndDate": "2022-06-12",
        "verifiedGraduated": "Yes",
        "verifiedGraduationDate": "2022-06-12",
        "verifiedContactName": "Registrar Services",
        "verifiedContactNumber": "+16507232300",
        "verifiedContactEmail": "[email protected]",
        "comments": "Confirmed via sealed transcript",
        "verifierFirstName": "Regina",
        "verifierLastName": "Sloane",
        "verifierPosition": "Registrar"
      },
      "verifier": {
        "firstName": "Regina",
        "lastName": "Sloane",
        "position": "Registrar"
      }
    },
    "accreditation": {
      "reference": {
        "name": "Stanford University",
        "date": "2022-06-12",
        "city": "Stanford",
        "state": "CA"
      },
      "matches": [
        {
          "campus": {
            "dapipId": "243744",
            "locationName": "Stanford University",
            "parentInstitution": null,
            "locationType": "Institution",
            "city": "Stanford",
            "state": "CA",
            "address": "450 Serra Mall, Stanford, CA 94305",
            "url": "https://www.stanford.edu"
          },
          "accreditation": {
            "statusLabel": "Accredited",
            "isAccredited": true,
            "accreditor": "Western Association of Schools and Colleges, Senior College and University Commission",
            "programName": "Institutional Accreditation",
            "validFrom": "1949-01-01",
            "validThrough": null,
            "reason": "Accredited by WASC Senior College and University Commission from 1949-01-01 through present",
            "latestAction": {
              "date": "2024-05-15",
              "description": "Renewal of Accreditation",
              "justification": "In compliance with all accreditation standards",
              "agencyName": "WASC Senior College and University Commission"
            },
            "recordTimeline": [
              {
                "status": "Accredited",
                "accreditor": "WASC Senior College and University Commission",
                "programName": "Institutional Accreditation",
                "startDate": "1949-01-01",
                "endDate": null
              }
            ]
          }
        }
      ],
      "suggestions": [],
      "metadata": {
        "campusesConsidered": 1,
        "checkedOn": "2025-12-02",
        "dataSource": "apps/verification-api/data/accreditation (InstitutionCampus, AccreditationRecords, AccreditationActions)",
        "accreditationStatus": "accredited"
      }
    }
  }
}

Example: Education Verification (No Record)

{
  "event": "verification.completed",
  "occurredAt": "2025-12-02T14:20:00.000Z",
  "data": {
    "searchId": "norecord-1234-5678-abcd-ef0123456789",
    "verificationId": "vr_norecord-9876-5432-dcba-fedcba987654",
    "externalSearchId": "edu-check-999",
    "searchType": "EDUCATION",
    "status": "Completed",
    "channel": "EMAIL",
    "verificationResult": {
      "id": "vr_norecord-9876-5432-dcba-fedcba987654",
      "searchId": "norecord-1234-5678-abcd-ef0123456789",
      "outcome": "NO_RECORD",
      "submittedAt": "2025-12-02T14:20:00.000Z",
      "createdAt": "2025-12-01T10:00:00.000Z",
      "updatedAt": "2025-12-02T14:20:00.000Z",
      "channel": "EMAIL",
      "additionalComments": "No enrollment record found for this individual",
      "discrepancy": false,
      "extractedData": {
        "educationVerified": false,
        "noRecord": true,
        "confidence": 0.95
      },
      "educationVerification": {
        "providedSchoolName": "State University",
        "providedLocation": "Columbus, OH",
        "providedDegree": "Bachelor of Arts",
        "providedMajor": "Psychology",
        "providedGraduationDate": "2019-05-15",
        "verifiedSchoolName": "State University",
        "verifiedDegree": null,
        "verifiedMajor": null,
        "verifiedGraduationDate": null,
        "comments": "Registrar confirmed no enrollment record exists for this individual"
      }
    }
  }
}

AccreditationResult Object

Included in education verification webhooks (verification.completed and verification.action_required).
FieldTypeDescription
referenceAccreditationReferenceInput parameters used for lookup
matchesAccreditationMatch[]Exact campus/institution matches
suggestionsCampusSummary[]Alternate campuses when no exact match
metadataAccreditationMetadataLookup metadata and status
notestringPresent when matches is empty; review instructions

AccreditationReference Object

FieldTypeDescription
namestringInstitution name used for lookup
datestringReference date (graduation/attendance)
citystringCity filter
statestringState filter

AccreditationMatch Object

FieldTypeDescription
campusCampusSummaryCampus/institution details
accreditationAccreditationEvaluationAccreditation status details

CampusSummary Object

FieldTypeDescription
dapipIdstringDatabase of Accredited Postsecondary Institutions ID
locationNamestringCampus name
parentInstitutionstringParent institution name
locationTypestringType: Institution, Branch, etc.
citystringCity
statestringState
addressstringFull address
urlstringInstitution website

AccreditationEvaluation Object

FieldTypeDescription
statusLabelstringHuman-readable status
isAccreditedbooleanAccreditation status
accreditorstringAccrediting agency name
programNamestringAccreditation program
validFromstringAccreditation start date
validThroughstringAccreditation end date (null if ongoing)
reasonstringExplanation of accreditation status
latestActionAccreditationActionMost recent accreditation action
recordTimelineAccreditationTimelineItem[]Historical accreditation records

AccreditationMetadata Object

FieldTypeDescription
campusesConsiderednumberNumber of campuses evaluated
checkedOnstringDate of accreditation check
dataSourcestringData source identifier
accreditationStatusAccreditationStatusAggregated status

AccreditationStatus Enum

ValueDescription
accreditedInstitution is currently accredited
not_accreditedInstitution is not accredited
unknownAccreditation status could not be determined
not_foundNo matching institution found

Event: verification.action_required

Sent when verification cannot proceed without manual intervention.

Data Fields

FieldTypeRequiredDescription
searchIdstring (UUID)YesSearch identifier
verificationIdstring (UUID)NoPresent when verification record exists
externalSearchIdstringNoExternal identifier
searchTypeSearchTypeNoType of verification
reasonCodeActionRequiredReasonCodeYesMachine-readable reason code
statusstringNoHuman-readable status
channelVerificationChannelNoChannel that triggered the action
contactContactPayloadNoStructured contact information
metadataobjectNoAdditional context and troubleshooting data
accreditationAccreditationResultNoAccreditation data (education with THIRD_PARTY_RECORD)

ActionRequiredReasonCode Enum

CodeDescriptionWhen Triggered
THIRD_PARTY_RECORDRequires third-party vendorResearch identified paywalled portal or vendor
UPSTREAM_ISSUEExternal service failureFax provider outage, email throttling, API failure
SYSTEM_FAILUREInternal system errorDatabase issue, workflow crash
SLA_REACHEDSLA timeout exceededSearch exceeded SLA without result
HUMAN_ESCALATIONAutomation exhaustedNo contacts found, retry cap hit, manual review needed
OTHERCatch-allCases not matching other codes

ContactPayload Object

Structured contact information based on search type.
FieldTypeDescription
typestringContact type: EMPLOYMENT, EDUCATION, LICENSE, REFERENCE
dataobjectType-specific contact data

EmploymentContactPayload

FieldTypeDescription
providedCompanyNamestringEmployer name
providedContactNamestringContact name
providedContactNumberstringContact phone
providedContactEmailstringContact email
providedLocationstringEmployer location
providedStartDatestringEmployment start date
providedEndDatestringEmployment end date
providedPositionstringJob title
providedSalarystringCompensation
providedAddress1stringAddress line 1
providedAddress2stringAddress line 2
providedCitystringCity
providedStatestringState
providedZipstringPostal code
doNotContactbooleanDo-not-contact flag

EducationContactPayload

FieldTypeDescription
providedSchoolNamestringInstitution name
providedLocationstringInstitution location
providedAddress1stringAddress line 1
providedAddress2stringAddress line 2
providedCitystringCity
providedStatestringState
providedZipstringPostal code
providedContactNamestringContact name
providedContactNumberstringContact phone
providedContactEmailstringContact email
providedDegreestringDegree
providedMajorstringMajor
providedMinorstringMinor
providedStartDatestringAttendance start
providedEndDatestringAttendance end
providedGraduatedstringGraduation status
providedGraduationDatestringGraduation date

LicenseContactPayload

FieldTypeDescription
providedAgencystringLicensing agency
providedLicenseNamestringLicense/certification name
providedLicenseNumberstringLicense number
providedReceiveDatestringIssue date
providedExpireDatestringExpiration date
providedStatestringIssuing jurisdiction

ReferenceContactPayload

FieldTypeDescription
providedCompanyNamestringCompany associated with reference
providedReferenceNamestringReference contact name
providedReferencePhonestringReference phone
providedReferenceEmailstringReference email
providedTypestringRelationship type (e.g., peer, manager)
providedRelationshipstringRelationship details
providedReferenceAddressstringReference address
providedReferenceCitystringCity
providedReferenceStatestringState
providedReferenceZipstringPostal code
providedLocationstringLocation summary
providedCommentsstringAdditional notes

Example: THIRD_PARTY_RECORD (Employment)

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T10:15:00.000Z",
  "data": {
    "searchId": "7b0463ae-a338-4b5f-bd5c-b3ef2e6e5ccc",
    "externalSearchId": "emp-001",
    "searchType": "EMPLOYMENT",
    "reasonCode": "THIRD_PARTY_RECORD",
    "status": "QA Review",
    "channel": "EMAIL",
    "metadata": {
      "source": "research",
      "contactIndex": 0,
      "vendor": "THE_WORK_NUMBER",
      "vendorCode": "15619",
      "vendorMatched": "TWN 15619 - uses The Work Number exclusively"
    },
    "contact": {
      "type": "EMPLOYMENT",
      "data": {
        "providedCompanyName": "Major Hospital Network",
        "providedContactName": "HR Department",
        "providedPosition": "Registered Nurse",
        "providedStartDate": "2020-03-15",
        "providedEndDate": "2024-08-01",
        "doNotContact": false
      }
    }
  }
}

Example: THIRD_PARTY_RECORD (Education with Accreditation)

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T18:05:00.000Z",
  "data": {
    "searchId": "ed_7b0463ae-a338-4b5f-bd5c-b3ef2e6e5ccc",
    "externalSearchId": "edu-req-90210",
    "searchType": "EDUCATION",
    "reasonCode": "THIRD_PARTY_RECORD",
    "status": "QA Review",
    "channel": "EMAIL",
    "metadata": {
      "source": "research",
      "contactIndex": 0,
      "vendor": "PARCHMENT",
      "vendorCode": "DIST-90833",
      "vendorMatched": "Parchment portal only"
    },
    "contact": {
      "type": "EDUCATION",
      "data": {
        "providedSchoolName": "Metro High School District",
        "providedLocation": "Memphis, TN",
        "providedContactName": "Records Office",
        "providedContactEmail": "[email protected]",
        "providedContactNumber": "+19015445566",
        "providedGraduationDate": "2018-05-25"
      }
    },
    "accreditation": {
      "reference": {
        "name": "Metro High School District",
        "date": "2018-05-25",
        "city": "Memphis",
        "state": "TN"
      },
      "matches": [
        {
          "campus": {
            "dapipId": "123456",
            "locationName": "Metro High School District",
            "city": "Memphis",
            "state": "TN",
            "url": "https://www.metrohsd.gov"
          },
          "accreditation": {
            "statusLabel": "Accredited",
            "isAccredited": true,
            "accreditor": "SACS",
            "reason": "Accredited by Southern Association of Colleges and Schools"
          }
        }
      ],
      "metadata": {
        "accreditationStatus": "accredited",
        "campusesConsidered": 1,
        "dataSource": "apps/verification-api/data/accreditation",
        "checkedOn": "2025-12-02"
      }
    }
  }
}

Example: UPSTREAM_ISSUE

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T06:12:00.000Z",
  "data": {
    "searchId": "search_voice_fax_884",
    "externalSearchId": "emp-upstream-001",
    "searchType": "EMPLOYMENT",
    "reasonCode": "UPSTREAM_ISSUE",
    "status": "Outbound Retry Cap",
    "channel": "EMAIL",
    "metadata": {
      "provider": "azureEmail",
      "errorCategory": "provider_timeout",
      "message": "Microsoft Graph throttled mailbox after 5 consecutive 503 responses",
      "lastAttemptAt": "2025-12-02T05:58:00.000Z",
      "retryCount": 3
    }
  }
}

Example: SYSTEM_FAILURE

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T14:30:00.000Z",
  "data": {
    "searchId": "ed_verif_540",
    "externalSearchId": "edu-sys-001",
    "searchType": "EDUCATION",
    "reasonCode": "SYSTEM_FAILURE",
    "status": "Workflow Error",
    "channel": "FAX",
    "metadata": {
      "errorCategory": "system",
      "stackId": "wf_education_outbound_20251202T1425",
      "retryCount": 1,
      "note": "Prisma write failure while persisting fax metadata"
    }
  }
}

Example: SLA_REACHED

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T18:22:00.000Z",
  "data": {
    "searchId": "lic_0f6b69ec-4de5-49a5-9aa0-3e94f3c6c4db",
    "externalSearchId": "lic-sla-001",
    "searchType": "LICENSE",
    "reasonCode": "SLA_REACHED",
    "status": "Awaiting Applicant Docs",
    "channel": "VOICE",
    "metadata": {
      "slaHours": 24,
      "elapsedMinutes": 1560,
      "lastAttemptAt": "2025-12-02T17:55:00.000Z",
      "reassignmentWindowMinutes": 2880,
      "note": "State board requires signed release"
    },
    "contact": {
      "type": "LICENSE",
      "data": {
        "providedAgency": "Texas Board of Nursing",
        "providedLicenseNumber": "RN-789654",
        "providedLicenseName": "Registered Nurse",
        "providedState": "TX"
      }
    }
  }
}

Example: HUMAN_ESCALATION

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T10:00:00.000Z",
  "data": {
    "searchId": "emp_7f8e9d0a-1b2c-3d4e-5f6a-7b8c9d0e1f2a",
    "externalSearchId": "emp-escalate-001",
    "searchType": "EMPLOYMENT",
    "reasonCode": "HUMAN_ESCALATION",
    "status": "QA Review",
    "channel": "EMAIL",
    "metadata": {
      "source": "automatic_reassignment",
      "createdAt": "2025-11-30T10:00:00.000Z",
      "reassignedAt": "2025-12-02T10:00:00.000Z",
      "outboundWindowMinutes": 1440,
      "reassignmentWindowMinutes": 2880,
      "exceededSla": true,
      "reachedReassignmentWindow": true,
      "contactPlan": {
        "contactResults": [
          {
            "source": "primary",
            "phone": "+14255551234",
            "email": "[email protected]",
            "confidence": 0.85,
            "metadata": {
              "title": "HR Manager",
              "department": "Human Resources"
            }
          }
        ],
        "researchNotes": "Found direct HR contact via company website",
        "researchConfidence": 0.92
      }
    }
  }
}

Example: OTHER

{
  "event": "verification.action_required",
  "occurredAt": "2025-12-02T09:15:00.000Z",
  "data": {
    "searchId": "ref_1205",
    "externalSearchId": "ref-other-001",
    "searchType": "REFERENCE",
    "reasonCode": "OTHER",
    "status": "Needs Clarification",
    "channel": "EMAIL",
    "metadata": {
      "note": "Reference replied with partial data; applicant name mismatch requires confirmation",
      "requiresHumanReview": true
    }
  }
}

Event: verification.notification

Sent during intermediate stages of verification process.

Data Fields

FieldTypeRequiredDescription
searchIdstring (UUID)YesSearch identifier
externalSearchIdstringNoExternal identifier
verificationIdstring (UUID)NoVerification record ID when linked
searchTypeSearchTypeNoType of verification
notificationTypeVerificationNotificationTypeNoNotification category
messageIdstringNoProvider message ID
threadIdstringNoConversation thread ID
fromstringNoSender identity
subjectstringNoSubject/description
classificationClassificationNoMessage classification
channelsVerificationChannel[]NoActive channels
contactPlanContactPlanEntry[]NoContact plan (when notificationType is CONTACT_PLAN)
outboundAttemptOutboundAttemptNoAttempt details (when notificationType is OUTBOUND_ATTEMPT)
inboundMetadataInboundMetadataNoInbound details (when notificationType is INBOUND_MESSAGE)

VerificationNotificationType Enum

ValueDescription
CONTACT_PLANResearch identified viable contacts
OUTBOUND_ATTEMPTOutbound communication attempt made
INBOUND_MESSAGEInbound communication received

Classification Object

FieldTypeDescription
typestringClassification label (e.g., VERIFICATION_RESPONSE, CALLBACK_REQUEST, INFO_REQUEST)
confidencenumberConfidence score (0-1)

ContactPlanEntry Object

FieldTypeDescription
namestringContact name
titlestringJob title/role
entityNamestringOrganization name
locationstringLocation
methodstringContact method: EMAIL, VOICE, FAX, or THIRD_PARTY
destinationstringEmail, phone, fax number, or vendor ID
sourcestringResearch source (e.g., Search history, Web)

OutboundAttempt Object

FieldTypeDescription
channelVerificationChannelChannel used
attemptNumbernumber1-based attempt index
contactNamestringContact name
contactTitlestringContact title
contactEntitystringOrganization
destinationstringEmail/phone/fax destination
metadataobjectChannel-specific details (e.g., { "callId": "..." })

InboundMetadata Object

FieldTypeDescription
summarystringContent summary
titlestringHeadline/title
ticketUrlstringLink to ticket/entry
linkLabelstringDisplay label for URL
sourcestringSource (e.g., MICROSOFT_GRAPH, FAX_WEBHOOK)

Example: CONTACT_PLAN

{
  "event": "verification.notification",
  "occurredAt": "2025-12-02T15:30:00.000Z",
  "data": {
    "searchId": "7c7b8f66-7f6a-4b52-9e85-8b3f5b7c1111",
    "externalSearchId": "contact-plan-001",
    "searchType": "EMPLOYMENT",
    "notificationType": "CONTACT_PLAN",
    "contactPlan": [
      {
        "name": "Casey Morgan",
        "title": "HR Generalist",
        "entityName": "St. Luke Medical Center",
        "location": "Denver, CO",
        "method": "EMAIL",
        "destination": "[email protected]",
        "source": "Search history"
      },
      {
        "name": "Nurse Staffing Desk",
        "title": null,
        "entityName": "St. Luke Medical Center",
        "location": "Denver, CO",
        "method": "VOICE",
        "destination": "+13035551234",
        "source": "Internal research"
      },
      {
        "name": null,
        "title": null,
        "entityName": "St. Luke Medical Center",
        "location": null,
        "method": "FAX",
        "destination": "+13035559876",
        "source": "Web"
      }
    ]
  }
}

Example: OUTBOUND_ATTEMPT

{
  "event": "verification.notification",
  "occurredAt": "2025-12-02T09:15:00.000Z",
  "data": {
    "searchId": "ba95128e-0e4e-4235-9b08-5554e4c95452",
    "externalSearchId": "emp-885",
    "searchType": "EMPLOYMENT",
    "notificationType": "OUTBOUND_ATTEMPT",
    "outboundAttempt": {
      "attemptNumber": 2,
      "channel": "VOICE",
      "contactName": "Patrice Wynn",
      "contactTitle": "HR Coordinator",
      "contactEntity": "Green Valley Rehab",
      "destination": "+17025559876",
      "metadata": {
        "callId": "call_23cb8da5",
        "callDurationSeconds": 145
      }
    }
  }
}

Example: INBOUND_MESSAGE (Email)

{
  "event": "verification.notification",
  "occurredAt": "2025-12-02T20:00:00.000Z",
  "data": {
    "searchId": "550e8400-e29b-41d4-a716-446655440000",
    "externalSearchId": "candidate-789",
    "verificationId": "660e8400-e29b-41d4-a716-446655440000",
    "searchType": "EMPLOYMENT",
    "notificationType": "INBOUND_MESSAGE",
    "messageId": "msg_abc123",
    "threadId": "thread_xyz789",
    "from": "[email protected]",
    "subject": "RE: Employment Verification Request",
    "classification": {
      "type": "VERIFICATION_RESPONSE",
      "confidence": 0.95
    },
    "channels": ["EMAIL"],
    "inboundMetadata": {
      "summary": "HR confirmed employment dates and job title",
      "source": "MICROSOFT_GRAPH"
    }
  }
}

Example: INBOUND_MESSAGE (Voice)

{
  "event": "verification.notification",
  "occurredAt": "2025-12-02T14:05:00.000Z",
  "data": {
    "searchId": "search_9c1d6a41-5ef1-4c80-9520-8456682e1d9f",
    "externalSearchId": "emp-voice-303",
    "verificationId": "vr_240d4e6a-abc9-4d0d-9e8f-5af18bb8acaf",
    "searchType": "EMPLOYMENT",
    "notificationType": "INBOUND_MESSAGE",
    "messageId": "msg_voice_456",
    "threadId": "thread_aggregate_123",
    "from": "+14255550123",
    "subject": "Voicemail transcription available",
    "classification": {
      "type": "CALLBACK_REQUEST",
      "confidence": 0.81
    },
    "channels": ["VOICE", "EMAIL"],
    "inboundMetadata": {
      "summary": "Caller requested callback to verify employment details",
      "source": "VOICEMAIL_TRANSCRIPTION"
    }
  }
}

Example: INBOUND_MESSAGE (Urgent)

{
  "event": "verification.notification",
  "occurredAt": "2025-12-02T18:04:00.000Z",
  "data": {
    "searchId": "search_04c7821e-8be3-4b4f-82b4-2a32b51e7f10",
    "externalSearchId": "emp-urgent-12",
    "verificationId": "vr_34d4d6e7-0bb1-46da-999b-d3625ddd7a54",
    "searchType": "EMPLOYMENT",
    "notificationType": "INBOUND_MESSAGE",
    "messageId": "msg_8891",
    "threadId": "thread_552",
    "from": "[email protected]",
    "subject": "RE: Verification needs signed release",
    "classification": {
      "type": "INFO_REQUEST",
      "confidence": 0.9
    },
    "channels": ["EMAIL"],
    "inboundMetadata": {
      "summary": "Clinic requires signed authorization before release",
      "title": "Authorization Required",
      "ticketUrl": "https://desk.example.com/tickets/1442",
      "linkLabel": "View Ticket",
      "source": "MICROSOFT_GRAPH"
    }
  }
}

Third-Party Vendor Reference

When reasonCode is THIRD_PARTY_RECORD, the metadata object includes vendor information.

Employment Vendors

Standardized NameSource Keywords
THE_WORK_NUMBERTALX, The Work Number, INVerify, WNFE
THOMAS_AND_COMPANYThomas and Company, Thomas & Co
PRECHECKPreCheck, EmpCheck, EmpChek
VERIFYTODAYVerifyToday, Verify Today System
CCCVERIFYCCC Verify, CCCVerify
EXPERIANuConfirm, Experian Verify
QUICKCONFIRMQuickConfirm
TRUEWORKTruework, True Work
VERISAFE_JOBSVerisafe Jobs
VAULT_VERIFYVaultVerify
VERIFY_FASTVerify Fast, VerifyFast
VERIFENTVerifent
VERIFY_ADVANTAGEVerifyAdvantage
TENSTREETTenstreet
TRUECONFIRMTrueConfirm
JOBTRAXJobTrax
VERIFICATION_MANAGERVerification Manager

Education Vendors

Standardized NameSource Keywords
NSCH_DEGREE_VERIFYNational Student Clearinghouse, NSC, NSCH, DegreeVerify, DiplomaVerify
PARCHMENTParchment
NEED_MY_TRANSCRIPTNeed My Transcript, NeedMyTranscript, needmytranscript.com
SCRIBORDERScribOrder, Scrib Order, scriborder.com
AURADATAAuraData, Aura Data, auradata.com
DIPLOMA_SENDERDiploma Sender, diplomasender.com
CERTREE_EDUCertree EDU
UNKNOWNUnrecognized vendor

Retry Policy

SettingDefaultDescription
Retry attempts3Maximum delivery attempts
BackoffExponential2s, 4s, 8s (with jitter)
4xx errorsNot retriedClient errors are final
5xx errorsRetriedServer errors are retried
Timeout30 secondsPer-request timeout

Configuration

Tenant webhook configuration via policy:
{
  "webhook": {
    "enabled": true,
    "secret": "your-webhook-secret",
    "retryAttempts": 3,
    "closeoutEndpoints": {
      "EMPLOYMENT": "https://your-api.com/webhooks/employment",
      "EDUCATION": "https://your-api.com/webhooks/education"
    },
    "fallbackEndpoint": "https://your-api.com/webhooks/verification"
  },
  "policy": {
    "global": {
      "searchSlaMinutes": 1440,
      "reassignmentWindowMinutes": 2880,
      "includeContactPlanInEscalation": false
    }
  }
}

Policy Parameters

ParameterDefaultDescription
searchSlaMinutes1440 (24h)Search SLA in minutes
reassignmentWindowMinutes2880 (48h)Auto-reassignment window
includeContactPlanInEscalationfalseInclude research data in escalation webhooks

Best Practices

1. Acknowledge Quickly

Return 2xx within 30 seconds:
app.post('/webhooks', async (req, res) => {
  res.status(200).send('OK')
  processWebhook(req.body).catch(console.error)
})

2. Verify Signatures

const signature = req.headers['x-webhook-signature']
if (!verifyWebhookSignature(req.rawBody, signature, secret)) {
  return res.status(401).send('Invalid signature')
}

3. Handle Idempotency

Use X-Event-Id to detect duplicates:
const eventId = req.headers['x-event-id']
if (await isProcessed(eventId)) {
  return res.status(200).send('Already processed')
}
await processWebhook(req.body)
await markAsProcessed(eventId)

4. Handle All Event Types

app.post('/webhooks', (req, res) => {
  const { event, data } = req.body

  switch (event) {
    case 'verification.completed':
      handleCompleted(data)
      break
    case 'verification.action_required':
      handleActionRequired(data)
      break
    case 'verification.notification':
      handleNotification(data)
      break
  }

  res.status(200).send('OK')
})

Testing

Sample Test Payload

{
  "event": "verification.completed",
  "occurredAt": "2025-12-02T20:00:00.000Z",
  "data": {
    "searchId": "test-search-id",
    "externalSearchId": "test-external-id",
    "verificationId": "test-verification-id",
    "searchType": "EMPLOYMENT",
    "status": "Completed",
    "channel": "EMAIL",
    "verificationResult": {
      "id": "test-result-id",
      "outcome": "VERIFIED",
      "extractedData": {
        "employmentVerified": true,
        "employerName": "Test Company",
        "jobTitle": "Software Engineer",
        "startDate": "2020-01-01",
        "endDate": "2023-12-31",
        "confidence": 0.95
      },
      "channel": "EMAIL"
    }
  }
}

Tools

  • ngrok: ngrok http 3000 for local testing
  • webhook.site: Temporary webhook URL for testing
  • Postman: Import payloads for manual testing