Skip to main content
Automation rules enable automatic decision-making during KYC session processing. Configure rules to automatically approve, deny, flag, or require manual review based on various conditions.

Overview

Automation rules are defined in the validation_config.automation_rules object of a workflow. When a session is processed, all enabled rules are evaluated and actions are triggered accordingly.
{
  "validation_config": {
    "automation_rules": {
      "enabled": true,
      "auto_process": true,
      "country_rules": [...],
      "list_match_rules": [...],
      "document_rules": [...],
      "form_field_rules": [...],
      "default_action": "manual_review"
    }
  }
}

Actions

All automation rules can trigger one of these actions:
ActionDescriptionEffect
auto_approveAutomatically approve the sessionSession status → approved
auto_denyAutomatically reject the sessionSession status → rejected
manual_reviewRequire human reviewSession status → manual_review
flagAdd alert to response (does not block)Flag added to automation_flags
no_actionNo action takenContinue processing
Actions are prioritized: auto_deny > manual_review > flag > auto_approve. If multiple rules trigger, the highest priority action wins.

Base Configuration

PropertyTypeDescription
enabledbooleanEnable automation rules processing (default: true)
auto_processbooleanAutomatically process session when all steps are completed. No manual POST /process needed. (default: false)
default_actionstringDefault action when no rules match and no auto-approve conditions met (default: manual_review)

Country Rules

Trigger actions based on nationality, residence, or incorporation country.
{
  "country_rules": [
    {
      "country_code": "KP",
      "action": "auto_deny",
      "applies_to": ["all"],
      "reason": "DPRK is a sanctioned country"
    },
    {
      "country_code": "IR",
      "action": "manual_review",
      "applies_to": ["nationality", "residence"],
      "reason": "High-risk jurisdiction"
    },
    {
      "country_code": "CH",
      "action": "flag",
      "applies_to": ["tax_residence"],
      "reason": "Swiss tax residence - enhanced due diligence"
    }
  ]
}

Properties

PropertyTypeRequiredDescription
country_codestringISO 3166-1 alpha-2 country code (e.g., US, KP, IR)
actionstringAction to trigger: auto_approve, auto_deny, manual_review, flag, no_action
applies_toarrayCountry field types: nationality, residence, incorporation, tax_residence, birth_country, business_operation, all. Default: ["all"]
reasonstringReason for this rule (for audit trail)

How It Works

Country rules match against:
  1. Country fields in forms with matching country_type
  2. Address fields with matching country_type
  3. Extracted document data (e.g., nationality from passport)
Use applies_to to differentiate between nationality and residence rules. A user with nationality: IR and residence: US can have different rules applied.

List Match Rules

Trigger actions based on sanctions/watchlist matches.
{
  "list_match_rules": [
    {
      "list_type": "any",
      "match_level": "high_confidence",
      "entity_scope": "all",
      "action": "auto_deny"
    },
    {
      "list_type": "pep",
      "match_level": "any",
      "entity_scope": "primary",
      "action": "manual_review"
    },
    {
      "list_type": "ofac",
      "match_level": "exact",
      "entity_scope": "related_parties",
      "action": "flag"
    }
  ]
}

Properties

PropertyTypeRequiredDescription
list_typestringList type: any, ofac, un, eu, uk, au, ca, pep, adverse_media. Default: any
match_levelstringConfidence level: any, high_confidence, exact. Default: any
entity_scopestringApply to: primary, related_parties, all. Default: all
actionstringAction to trigger

Entity Scope

ScopeDescription
primaryOnly the main individual/company being onboarded
related_partiesDirectors, shareholders, beneficial owners (from entity_array fields)
allBoth primary subject and related parties
If you have different risk appetite for directors vs the primary subject, use multiple rules with different entity_scope values.

Face Deduplication

Detect repeat applicants by comparing faces across sessions.

Configuration

{
  "face_dedup_config": {
    "enabled": true,
    "auto_add_to_index": true,
    "similarity_threshold": 0.92
  },
  "face_dedup_rules": [
    {
      "min_previous_sessions": 1,
      "include_approved": true,
      "include_rejected": true,
      "include_pending": false,
      "action": "flag"
    },
    {
      "min_previous_sessions": 3,
      "include_approved": true,
      "include_rejected": true,
      "include_pending": false,
      "action": "auto_deny"
    }
  ]
}

Config Properties

PropertyTypeDescription
enabledbooleanEnable face deduplication (default: false)
auto_add_to_indexbooleanAutomatically add new faces to the deduplication index (default: true)
similarity_thresholdnumberThreshold to consider faces as same person (0-1). Default: 0.92

Rule Properties

PropertyTypeRequiredDescription
min_previous_sessionsintegerMinimum number of previous sessions to trigger rule (≥1)
include_approvedbooleanCount approved sessions (default: true)
include_rejectedbooleanCount rejected sessions (default: true)
include_pendingbooleanCount pending/processing sessions (default: false)
actionstringAction to trigger

Use Cases

  • Flag repeat applicants: Detect when same person applies multiple times
  • Fraud prevention: Auto-deny after 3+ rejected applications
  • Account linking: Identify potential duplicate accounts

Document Rules

Validate document age, expiration, validity, and image quality.
{
  "document_rules": [
    {
      "document_types": ["id", "passport"],
      "max_days_until_expiry": 90,
      "expiry_action": "flag",
      "expired_action": "auto_deny",
      "reject_invalid_documents": true,
      "invalid_document_action": "auto_deny",
      "min_image_quality": "acceptable",
      "poor_quality_action": "manual_review"
    },
    {
      "document_types": ["proof_of_address"],
      "max_days_since_issue": 90,
      "age_action": "flag"
    }
  ]
}

Properties

PropertyTypeDescription
document_typesarrayDocument types: id, passport, proof_of_address, all. Default: ["all"]
max_days_until_expiryintegerTrigger if document expires within this many days
expiry_actionstringAction when document is near expiry. Default: flag
min_days_since_issueintegerTrigger if document was issued less than this many days ago (too new)
max_days_since_issueintegerTrigger if document was issued more than this many days ago (too old)
age_actionstringAction for document age violations. Default: flag
expired_actionstringAction when document is already expired. Default: auto_deny
reject_invalid_documentsbooleanReject documents where is_valid_document=false. Default: true
invalid_document_actionstringAction when document type doesn’t match expected. Default: auto_deny
min_image_qualitystringMinimum quality: excellent, good, acceptable
poor_quality_actionstringAction when image quality is below threshold. Default: manual_review

Document Validation Checks

CheckDescription
max_days_until_expiryDocument expires soon (e.g., within 90 days)
expiredDocument is already expired
min_days_since_issueDocument was issued too recently (possible fraud)
max_days_since_issueDocument is too old (e.g., proof of address > 90 days)
is_valid_documentDocument type matches expected (not a pet photo)
image_qualityImage is clear, readable, properly lit

Extraction Validation Rules

Run additional validations on fields extracted from documents.
{
  "extraction_validation_rules": [
    {
      "rule_id": "company_name_sanctions",
      "description": "Check extracted company name against sanctions",
      "extracted_field": "company_name",
      "from_document_types": ["articles_of_incorporation", "tax_certificate"],
      "validations": ["sanctions_lists"],
      "action_on_match": "auto_deny",
      "action_on_error": "flag"
    },
    {
      "rule_id": "name_cross_validate",
      "description": "Validate extracted name matches form",
      "extracted_field": "full_name",
      "from_document_types": ["id", "passport"],
      "validations": ["cross_validate_form"],
      "cross_validate_with_field": "full_name",
      "cross_validate_similarity_threshold": 0.8,
      "action_on_mismatch": "flag"
    }
  ]
}

Properties

PropertyTypeRequiredDescription
rule_idstringUnique identifier for this rule
descriptionstringHuman-readable description
extracted_fieldstringName of extracted field to validate (e.g., full_name, company_name, tax_id)
from_document_typesarrayOnly apply to these document types. Default: ["all"]
validationsarrayList of validation types to run
cross_validate_with_fieldstringForm field_id to compare against (for cross_validate_form)
cross_validate_similarity_thresholdnumberMinimum similarity score for cross-validation (0-1). Default: 0.8
custom_validation_lambdastringLambda function ARN for custom validation
action_on_matchstringAction when validation finds an issue. Default: manual_review
action_on_mismatchstringAction when cross-validation fails. Default: flag
action_on_errorstringAction when validation service fails. Default: flag

Validation Types

TypeDescription
sanctions_listsCheck against OFAC, UN, EU lists
adverse_mediaNews/media screening
cross_validate_formCompare with form data
pep_checkPolitically Exposed Persons check
company_registryCompany registration lookup
tax_registryTax ID validation
customCustom validation Lambda

Form Field Rules

Trigger actions based on user-declared form field values.
{
  "form_field_rules": [
    {
      "field_id": "pep_status",
      "operator": "in",
      "value": ["Yes - Current PEP", "Yes - Former PEP", "Yes - Family member of PEP"],
      "action": "manual_review",
      "reason": "User declared PEP status"
    },
    {
      "field_id": "high_risk_activity",
      "operator": "is_true",
      "action": "flag",
      "reason": "User declared high-risk activity"
    },
    {
      "field_id": "source_of_funds",
      "operator": "equals",
      "value": "Cryptocurrency",
      "action": "manual_review",
      "reason": "Crypto source of funds requires enhanced DD"
    }
  ]
}

Properties

PropertyTypeRequiredDescription
field_idstringThe field_id of the form field to evaluate
operatorstringComparison operator (see table below)
valueanyValue or list of values to compare against (not required for is_true, is_false, is_empty, is_not_empty)
actionstringAction to trigger when condition is met
reasonstringHuman-readable reason (for audit trail and UI)

Operators

OperatorDescriptionValue Required
equalsExact matchYes
not_equalsNot equalYes
inValue is in listYes (array)
not_inValue is not in listYes (array)
containsString containsYes
not_containsString doesn’t containYes
is_trueBoolean is trueNo
is_falseBoolean is falseNo
is_emptyField is empty/nullNo
is_not_emptyField has valueNo
gtGreater thanYes
ltLess thanYes
gteGreater than or equalYes
lteLess than or equalYes

Volume Rules

Trigger actions based on declared transaction volume.
{
  "volume_rules": [
    {
      "min_monthly_volume": 100000,
      "action": "manual_review"
    },
    {
      "min_monthly_volume": 1000000,
      "action": "flag"
    },
    {
      "min_monthly_transactions": 10000,
      "action": "flag"
    }
  ]
}

Properties

PropertyTypeRequiredDescription
min_monthly_volumenumberMinimum monthly volume in USD to trigger (if above)
max_monthly_volumenumberMaximum monthly volume in USD to trigger (if below)
min_monthly_transactionsnumberMinimum monthly transaction count to trigger
max_monthly_transactionsnumberMaximum monthly transaction count to trigger
actionstringAction to trigger
Volume rules apply to volume fields and currency fields with apply_volume_rules: true.

Time to Complete Rules

Trigger actions based on how long the session took to complete.
{
  "time_to_complete_rules": [
    {
      "min_seconds": 30,
      "action": "flag"
    },
    {
      "max_seconds": 86400,
      "action": "flag"
    }
  ]
}

Properties

PropertyTypeRequiredDescription
min_secondsintegerMinimum acceptable completion time. Triggers if completed faster (potential bot).
max_secondsintegerMaximum acceptable completion time. Triggers if slower (abandoned/suspicious).
actionstringAction to trigger

Use Cases

  • Bot detection: Flag if completed in < 30 seconds
  • Abandonment: Flag if took > 24 hours

Email Verification Rules

Trigger actions based on email verification results.
{
  "email_verification_config": {
    "enabled": true,
    "provider": "internal"
  },
  "email_verification_rules": {
    "on_invalid": "auto_deny",
    "on_disposable": "flag",
    "on_role_based": "flag",
    "on_unverifiable": "flag"
  }
}

Config Properties

PropertyTypeDescription
enabledbooleanEnable email verification. Default: false
providerstringProvider: zerobounce, neverbounce, hunter, internal. Default: internal

Rule Properties

PropertyTypeDescription
on_invalidstringAction when email is invalid/does not exist. Default: auto_deny
on_disposablestringAction when email is from disposable/temporary domain. Default: flag
on_role_basedstringAction when email is role-based (info@, admin@). Default: flag
on_unverifiablestringAction when email cannot be verified (catch-all domain). Default: flag

Face Match Rules

Configure face matching between ID photo and selfie/liveness.
{
  "face_match_threshold": 0.85,
  "face_match_action_on_fail": "auto_deny"
}

Properties

PropertyTypeDescription
face_match_thresholdnumberThreshold for face matching (0-1). Default: 0.85
face_match_action_on_failstringAction when face match fails. Default: auto_deny

Web Validation Rules

Comprehensive rules for website/domain validation. See Web Validation for background.
{
  "web_validation_rules": {
    "enabled": true,
    
    "score_rules": [
      {"min_score": 70, "action": "auto_approve"},
      {"max_score": 40, "action": "auto_deny"}
    ],
    
    "ssl_rules": {
      "on_no_ssl": "auto_deny",
      "on_invalid_ssl": "manual_review",
      "min_days_until_expiry": 30,
      "expiry_action": "flag"
    },
    
    "page_status_rules": [
      {"status": "DOWN", "action": "auto_deny"},
      {"status": "UNDER_CONSTRUCTION", "action": "flag"},
      {"status": "INCOMPLETE_TEMPLATE", "action": "flag"}
    ],
    
    "industry_rules": {
      "blocked_industries": ["Gambling", "Adult Content", "Weapons"],
      "on_blocked": "auto_deny",
      "on_mismatch": "flag",
      "min_confidence": 0.7
    },
    
    "adverse_media_rules": {
      "on_high_risk": "auto_deny",
      "on_medium_risk": "manual_review",
      "on_low_risk": "flag"
    },
    
    "sanction_rules": {
      "on_match": "auto_deny",
      "lists_to_check": ["ofac", "un", "eu", "uk"]
    },
    
    "social_media_rules": {
      "on_no_social": "flag",
      "on_all_invalid": "manual_review",
      "min_valid_links": 1
    },
    
    "tranco_rules": {
      "on_not_ranked": "flag",
      "band_actions": {
        "top_10k": "auto_approve",
        "not_ranked": "manual_review"
      }
    },
    
    "page_evidence_rules": {
      "on_unrealistic_promises": "auto_deny",
      "on_no_contact_info": "flag",
      "require_phone": true,
      "require_email": true
    }
  }
}

Rule Components

Trigger actions based on overall reliability score (0-100).
PropertyTypeDescription
min_scorenumberMinimum score to trigger (triggers if score >= min)
max_scorenumberMaximum score to trigger (triggers if score < max)
actionstringAction to trigger
Rules for SSL certificate validation.
PropertyTypeDescription
on_no_sslstringAction when site has no SSL. Default: ‘auto_deny’
on_invalid_sslstringAction when SSL is invalid/expired. Default: ‘manual_review’
min_days_until_expiryintegerTrigger if SSL expires within this many days
expiry_actionstringAction when SSL is near expiry. Default: ‘flag’
Rules for specific page statuses.
StatusDescription
INCOMPLETE_TEMPLATESite appears to be a template
UNDER_CONSTRUCTIONUnder construction page
DOWNSite is down
MAINTENANCEMaintenance mode
NOT_AVAILABLENot available
GEO_RESTRICTEDGeographically restricted
Rules for industry classification.
PropertyTypeDescription
blocked_industriesarrayIndustry names/IDs that trigger rule
on_blockedstringAction when industry is blocked. Default: ‘auto_deny’
on_mismatchstringAction when detected industry doesn’t match declared. Default: ‘flag’
min_confidencenumberMinimum confidence for industry classification (0-1). Default: 0.7
Rules for adverse media check results.
PropertyTypeDescription
on_high_riskstringAction for HIGH_RISK decision (76-100). Default: ‘auto_deny’
on_medium_riskstringAction for MEDIUM_RISK decision (51-75). Default: ‘manual_review’
on_low_riskstringAction for LOW_RISK decision (26-50). Default: ‘flag’
min_risk_scorenumberCustom threshold: trigger if adverse media risk >= value
custom_actionstringAction for custom min_risk_score threshold
Rules for domain sanction check.
PropertyTypeDescription
on_matchstringAction when domain found on sanction lists. Default: ‘auto_deny’
lists_to_checkarrayLists to check: ‘ofac’, ‘un’, ‘eu’, ‘uk’, ‘au’, ‘ca’, ‘world_bank’, etc.
Rules for social media presence.
PropertyTypeDescription
on_no_socialstringAction when no social links found. Default: ‘flag’
on_all_invalidstringAction when all social links are invalid. Default: ‘manual_review’
min_valid_linksintegerMinimum valid social links required. Default: 1
required_platformsarrayPlatforms that must be present
on_missing_requiredstringAction when required platform missing. Default: ‘flag’
Rules based on Tranco popularity ranking.
PropertyTypeDescription
on_not_rankedstringAction when site not in top 1M. Default: ‘flag’
min_rankintegerTrigger if rank is worse (higher number)
band_actionsobjectActions per ranking band: ‘top_10k’, ‘top_100k’, ‘top_500k’, ‘top_1m’, ‘not_ranked’
Rules for page content evidence.
PropertyTypeDescription
on_unrealistic_promisesstringAction for scam-like promises. Default: ‘auto_deny’
on_no_contact_infostringAction for no contact info. Default: ‘flag’
on_no_real_productsstringAction for placeholder products. Default: ‘flag’
on_no_navigationstringAction for no functional navigation. Default: ‘flag’
require_phonebooleanRequire phone number in contact
require_emailbooleanRequire email in contact
require_addressbooleanRequire physical address
on_missing_required_contactstringAction when required contact missing. Default: ‘flag’

Watchlist Auto-Add

Automatically add entities to watchlists based on session outcome.
{
  "watchlist_auto_add": {
    "enabled": true,
    "async_add": true,
    "deduplicate": true,
    "return_subject_ids": false,
    "rules": [
      {
        "trigger_on": "rejected",
        "watchlist_id": "wl_rejected_applicants",
        "ttl_days": 365,
        "tags": ["auto-added", "rejected"],
        "include_automation_flags": true,
        "include_entity_type_tag": true,
        "entity_types": ["individual", "company"],
        "enabled": true
      },
      {
        "trigger_on": "approved",
        "watchlist_id": "wl_customers",
        "entity_types": ["individual", "ubo"],
        "enabled": true
      }
    ]
  }
}

Config Properties

PropertyTypeDescription
enabledbooleanEnable watchlist auto-add feature. Default: true
async_addbooleanAdd to watchlist asynchronously. Set false to get subject_ids (slower). Default: true
deduplicatebooleanAvoid adding same name twice from same session. Default: true
return_subject_idsbooleanIf true, forces sync invocation to return subject_ids. Default: false

Rule Properties

PropertyTypeRequiredDescription
trigger_onstringSession outcome: approved, rejected, flagged, manual_review
watchlist_idstringTarget watchlist ID to add subjects to
ttl_daysintegerOverride default TTL for subjects (days)
tagsarrayAdditional tags to add to each subject
include_automation_flagsbooleanAdd triggered automation rule flags as subject tags. Default: true
include_entity_type_tagbooleanAdd entity type as tag. Default: true
entity_typesarrayEntity types: individual, company, ubo, director, shareholder, domain, wallet. Empty = all.
enabledbooleanWhether this rule is enabled. Default: true

Entity Types

TypeDescription
individualPrimary individual subject
companyPrimary company subject
uboUltimate beneficial owners
directorCompany directors
shareholderShareholders
domainWebsite domains
walletCrypto wallet addresses

Complete Example

{
  "validation_config": {
    "run_lists": true,
    "run_adverse_media": true,
    "auto_face_match": true,
    "face_match_threshold": 0.85,
    "automation_rules": {
      "enabled": true,
      "auto_process": true,
      
      "country_rules": [
        {"country_code": "KP", "action": "auto_deny", "applies_to": ["all"], "reason": "DPRK"},
        {"country_code": "IR", "action": "manual_review", "applies_to": ["nationality"]}
      ],
      
      "list_match_rules": [
        {"list_type": "any", "match_level": "high_confidence", "action": "auto_deny"},
        {"list_type": "pep", "entity_scope": "primary", "action": "manual_review"}
      ],
      
      "face_dedup_config": {
        "enabled": true,
        "similarity_threshold": 0.92
      },
      "face_dedup_rules": [
        {"min_previous_sessions": 1, "include_rejected": true, "action": "flag"},
        {"min_previous_sessions": 3, "action": "auto_deny"}
      ],
      
      "document_rules": [
        {
          "document_types": ["id", "passport"],
          "max_days_until_expiry": 90,
          "expiry_action": "flag",
          "expired_action": "auto_deny",
          "reject_invalid_documents": true,
          "min_image_quality": "acceptable",
          "poor_quality_action": "manual_review"
        }
      ],
      
      "form_field_rules": [
        {
          "field_id": "pep_status",
          "operator": "not_equals",
          "value": "No",
          "action": "manual_review",
          "reason": "User declared PEP status"
        }
      ],
      
      "email_verification_config": {"enabled": true},
      "email_verification_rules": {
        "on_invalid": "auto_deny",
        "on_disposable": "flag"
      },
      
      "face_match_threshold": 0.85,
      "face_match_action_on_fail": "auto_deny",
      
      "default_action": "manual_review",
      
      "watchlist_auto_add": {
        "enabled": true,
        "rules": [
          {
            "trigger_on": "rejected",
            "watchlist_id": "wl_rejected",
            "ttl_days": 365,
            "entity_types": ["individual"]
          }
        ]
      }
    }
  }
}

Processing Flow

When a session is processed with automation rules:
  1. Validation runs: Lists, adverse media, crypto, face match
  2. Rules evaluated: All applicable rules are checked
  3. Actions collected: All triggered actions are recorded
  4. Final decision: Highest priority action determines outcome
  5. Watchlist add: If configured, entities are added to watchlists
  6. Response returned: Includes automation_flags and final_decision

Response with Automation Results

{
  "status": "success",
  "data": {
    "session_id": "...",
    "status": "manual_review",
    "processing_results": {
      "final_decision": "manual_review",
      "automation_flags": [
        {
          "rule_type": "country_rule",
          "action": "manual_review",
          "reason": "High-risk jurisdiction",
          "details": {"country_code": "IR", "field": "nationality"}
        },
        {
          "rule_type": "form_field_rule",
          "action": "manual_review",
          "reason": "User declared PEP status",
          "details": {"field_id": "pep_status", "value": "Yes - Current PEP"}
        }
      ],
      "watchlist_subjects_added": [
        {"watchlist_id": "wl_rejected", "subject_id": "subj_abc123"}
      ]
    }
  }
}