Skip to main content

Ongoing Monitoring

Verification is not a one-time event. Regulatory requirements mandate periodic re-screening, check expiry management, and triggered re-verification when circumstances change.
Regulatory requirements mandate periodic re-screening. Failure to re-screen customers at appropriate intervals can result in regulatory penalties and compliance failures.

Re-Screening

Use the standalone screening endpoint to re-screen existing customers against PEP, sanctions, adverse media, and watchlist databases.
curl -X POST \
  "https://instance.prod.onboardapp.io/api/gateway/execute/{project_hash}/screening/api" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your-api-key" \
  -H "X-SYNC-TIMEOUT: 30000" \
  -d '{
    "name": "Jane Smith",
    "date_of_birth": "1990-06-15",
    "country": "GB",
    "entity_type": "person",
    "categories": ["pep", "sanctions", "adverse_media", "watchlist"],
    "external_reference": "REVIEW-CUST-1234-2026Q1"
  }'
Re-screening uses the same endpoint and response format as initial screening. See the Screening Quickstart for full request and response details.

Re-Screening Intervals

Schedule re-screening frequency based on the customer’s risk tier:
Risk TierRecommended IntervalRationale
HighEvery 6 monthsHighest regulatory scrutiny. Frequent changes in sanctions lists and PEP databases.
MediumEvery 12 monthsStandard CDD cycle. Aligns with most regulatory frameworks.
LowEvery 24 monthsReduced frequency appropriate for low-risk customers with stable profiles.
These intervals are recommendations. Your compliance program may require different schedules based on jurisdiction, customer type, or regulatory guidance.

Implementing a Re-Screening Schedule

Implement a review calendar that automatically schedules re-screening based on the risk tier returned in the compliance report. Use the next_review_date field from the compliance metadata to track when each customer is due.
screening-scheduler.js
async function scheduleReScreening(customerId, riskTier) {
  const intervals = {
    High: 6, // months
    Medium: 12,
    Low: 24
  };

  const months = intervals[riskTier] || 12;
  const nextReviewDate = new Date();
  nextReviewDate.setMonth(nextReviewDate.getMonth() + months);

  await db.customers.update(customerId, {
    next_screening_date: nextReviewDate,
    risk_tier: riskTier
  });
}

// Run daily: find customers due for re-screening
async function processScheduledScreenings() {
  const due = await db.customers.find({
    next_screening_date: { $lte: new Date() },
    status: "active"
  });

  for (const customer of due) {
    await submitScreening(customer);
  }
}

Check Validity and Expiry

Verification checks have defined validity periods. After a check expires, it should be re-run before relying on its results.
Check CategoryValidity PeriodRationale
Identity365 daysIdentity documents and database records are relatively stable
Screening90 daysPEP, sanctions, and adverse media databases update frequently
Company180 daysCompany registry data changes with filings, director appointments
Financial365 daysFinancial records change annually with audits
EDD180 daysEnhanced due diligence findings may become stale quickly
Zenoo tracks check expiry dates internally. The compliance report includes validity information for each check:
{
  "checks_summary": {
    "checks": [
      {
        "type": "Company Screening",
        "status": "Pass",
        "completed_at": "2026-01-15T14:30:20Z",
        "valid_until": "2026-04-15T14:30:20Z"
      },
      {
        "type": "Company Registration",
        "status": "Pass",
        "completed_at": "2026-01-15T14:30:15Z",
        "valid_until": "2026-07-15T14:30:15Z"
      }
    ]
  }
}
Use the valid_until field to schedule check renewal before expiry.

Cross-Case Deduplication

When running a new verification on an entity that has been verified before, Zenoo automatically evaluates whether existing checks are still valid.
You are not charged for reused checks. Zenoo automatically deduplicates checks across cases, so you only pay for checks that are actually executed.
How it works:
  1. You submit a verification for an entity.
  2. Zenoo checks if the same entity has valid (non-expired) checks from a previous verification.
  3. Valid checks are reused. Only expired or missing checks are run fresh.
  4. Reused checks are marked with their original source case for audit traceability.
This means:
  • You are not charged for reused checks.
  • Results are returned faster (reused checks are instant).
  • Audit trail shows the provenance of each check.
Cross-case deduplication is automatic. You do not need to implement any special logic. Just submit verifications as normal.

What Gets Reused

Check TypeReuse EligibleCondition
Company RegistrationYesWithin validity period
PEP/Sanctions ScreeningYesWithin 90-day validity
Identity VerificationYesWithin 365-day validity
Document VerificationYesWithin 365-day validity, document not expired
Financial ChecksYesWithin 365-day validity
Biometric LivenessNoAlways re-run (presence must be current)

Triggered Re-Verification

Beyond scheduled re-screening, certain events should trigger an immediate re-verification:
Action: New UBO, ownership restructureChecks to Run: Full Company Verification (registry + screening on new individuals)
Action: News article, regulatory actionChecks to Run: Screening re-run + manual review
Action: Company re-domiciles, individual relocatesChecks to Run: Full re-verification in new jurisdiction
Action: New sanctions list update, regulatory directiveChecks to Run: Screening re-run on affected entities
Action: Name change, new documentsChecks to Run: Identity re-verification
Action: Scheduled review date reachedChecks to Run: Screening at minimum, full re-verification for high risk
Action: Unusual activity flagged by your systemsChecks to Run: Screening + EDD
For triggered re-verification, submit a new verification request with a new external_reference that reflects the trigger:
curl -X POST \
  "https://instance.prod.onboardapp.io/api/gateway/execute/{project_hash}/api" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your-api-key" \
  -H "X-SYNC-TIMEOUT: 30000" \
  -d '{
    "company_name": "Acme Holdings Ltd",
    "registration_number": "12345678",
    "country": "GB",
    "external_reference": "TRIGGER-ADVERSE-ACME-2026-0215"
  }'

Batch Screening

For ongoing monitoring of your entire customer base, submit multiple entities to the screening endpoint. Each request screens one entity, but you can submit many requests in parallel.
batch-screening.js
async function batchScreen(customers) {
  const CONCURRENCY = 10; // respect rate limits
  const results = [];

  for (let i = 0; i < customers.length; i += CONCURRENCY) {
    const batch = customers.slice(i, i + CONCURRENCY);

    const batchResults = await Promise.all(
      batch.map((customer) =>
        screenEntity({
          name: customer.name,
          date_of_birth: customer.dob,
          country: customer.country,
          entity_type: customer.type,
          categories: ["pep", "sanctions", "adverse_media", "watchlist"],
          external_reference: `BATCH-${customer.id}-${Date.now()}`
        })
      )
    );

    results.push(...batchResults);

    // Respect rate limits between batches
    if (i + CONCURRENCY < customers.length) {
      await sleep(1000);
    }
  }

  return results;
}
Monitor your rate limits when running batch operations. Contact Zenoo to request higher limits for large batch runs.

Monitoring Alerts

When re-screening returns new matches, Zenoo generates alerts in the case management system:
Alert TypeTriggerSeverity
PEP MatchEntity newly appears in a PEP databaseMedium (Class 3-4) or High (Class 1-2)
Sanctions HitEntity newly appears on a sanctions listCritical. Immediate escalation required.
Adverse MediaNew negative media articles foundMedium. Manual review required.
Status ChangePreviously clear entity now has matchesDepends on match type
New matches found during re-screening are compared against the previous screening results. Only genuinely new matches generate alerts, not previously reviewed and dismissed matches.

Next Review Date

The compliance report includes a recommended next review date based on the customer’s risk tier:
{
  "compliance_metadata": {
    "cdd_completed": true,
    "cdd_completed_at": "2026-01-15T14:32:00Z",
    "next_review_date": "2026-07-15",
    "risk_tier": "High",
    "edd_required": false
  }
}
Use the next_review_date field to schedule the next periodic review in your system. This date is calculated based on the risk tier using the intervals in the re-screening table above.

Building a Review Calendar

review-calendar.js
async function processCompletedVerification(result) {
  const { case_reference, compliance_metadata } = result;

  // Store review date from the compliance report
  await db.reviews.create({
    case_reference,
    customer_id: result.external_reference,
    completed_at: compliance_metadata.cdd_completed_at,
    next_review: compliance_metadata.next_review_date,
    risk_tier: compliance_metadata.risk_tier
  });

  // Schedule a reminder 30 days before review is due
  const reminderDate = new Date(compliance_metadata.next_review_date);
  reminderDate.setDate(reminderDate.getDate() - 30);

  await scheduler.schedule(reminderDate, "review-reminder", {
    case_reference,
    customer_id: result.external_reference
  });
}

Next Steps