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:
Action Description Effect auto_approveAutomatically approve the session Session status → approved auto_denyAutomatically reject the session Session status → rejected manual_reviewRequire human review Session status → manual_review flagAdd alert to response (does not block) Flag added to automation_flags no_actionNo action taken Continue processing
Actions are prioritized: auto_deny > manual_review > flag > auto_approve. If multiple rules trigger, the highest priority action wins.
Base Configuration
Property Type Description enabledboolean Enable automation rules processing (default: true) auto_processboolean Automatically process session when all steps are completed. No manual POST /process needed. (default: false) default_actionstring Default 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
Property Type Required Description country_codestring ✓ ISO 3166-1 alpha-2 country code (e.g., US, KP, IR) actionstring ✓ Action to trigger: auto_approve, auto_deny, manual_review, flag, no_action applies_toarray Country field types: nationality, residence, incorporation, tax_residence, birth_country, business_operation, all. Default: ["all"] reasonstring Reason for this rule (for audit trail)
How It Works
Country rules match against:
Country fields in forms with matching country_type
Address fields with matching country_type
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
Property Type Required Description list_typestring List type: any, ofac, un, eu, uk, au, ca, pep, adverse_media. Default: any match_levelstring Confidence level: any, high_confidence, exact. Default: any entity_scopestring Apply to: primary, related_parties, all. Default: all actionstring ✓ Action to trigger
Entity Scope
Scope Description 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
Property Type Description enabledboolean Enable face deduplication (default: false) auto_add_to_indexboolean Automatically add new faces to the deduplication index (default: true) similarity_thresholdnumber Threshold to consider faces as same person (0-1). Default: 0.92
Rule Properties
Property Type Required Description min_previous_sessionsinteger ✓ Minimum number of previous sessions to trigger rule (≥1) include_approvedboolean Count approved sessions (default: true) include_rejectedboolean Count rejected sessions (default: true) include_pendingboolean Count pending/processing sessions (default: false) actionstring ✓ Action 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
Property Type Description document_typesarray Document types: id, passport, proof_of_address, all. Default: ["all"] max_days_until_expiryinteger Trigger if document expires within this many days expiry_actionstring Action when document is near expiry. Default: flag min_days_since_issueinteger Trigger if document was issued less than this many days ago (too new) max_days_since_issueinteger Trigger if document was issued more than this many days ago (too old) age_actionstring Action for document age violations. Default: flag expired_actionstring Action when document is already expired. Default: auto_deny reject_invalid_documentsboolean Reject documents where is_valid_document=false. Default: true invalid_document_actionstring Action when document type doesn’t match expected. Default: auto_deny min_image_qualitystring Minimum quality: excellent, good, acceptable poor_quality_actionstring Action when image quality is below threshold. Default: manual_review
Document Validation Checks
Check Description 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
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
Property Type Required Description rule_idstring Unique identifier for this rule descriptionstring Human-readable description extracted_fieldstring ✓ Name of extracted field to validate (e.g., full_name, company_name, tax_id) from_document_typesarray Only apply to these document types. Default: ["all"] validationsarray ✓ List of validation types to run cross_validate_with_fieldstring Form field_id to compare against (for cross_validate_form) cross_validate_similarity_thresholdnumber Minimum similarity score for cross-validation (0-1). Default: 0.8 custom_validation_lambdastring Lambda function ARN for custom validation action_on_matchstring Action when validation finds an issue. Default: manual_review action_on_mismatchstring Action when cross-validation fails. Default: flag action_on_errorstring Action when validation service fails. Default: flag
Validation Types
Type Description 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
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
Property Type Required Description field_idstring ✓ The field_id of the form field to evaluate operatorstring ✓ Comparison operator (see table below) valueany Value or list of values to compare against (not required for is_true, is_false, is_empty, is_not_empty) actionstring ✓ Action to trigger when condition is met reasonstring Human-readable reason (for audit trail and UI)
Operators
Operator Description Value Required equalsExact match Yes not_equalsNot equal Yes inValue is in list Yes (array) not_inValue is not in list Yes (array) containsString contains Yes not_containsString doesn’t contain Yes is_trueBoolean is true No is_falseBoolean is false No is_emptyField is empty/null No is_not_emptyField has value No gtGreater than Yes ltLess than Yes gteGreater than or equal Yes lteLess than or equal Yes
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
Property Type Required Description min_monthly_volumenumber Minimum monthly volume in USD to trigger (if above) max_monthly_volumenumber Maximum monthly volume in USD to trigger (if below) min_monthly_transactionsnumber Minimum monthly transaction count to trigger max_monthly_transactionsnumber Maximum monthly transaction count to trigger actionstring ✓ Action 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
Property Type Required Description min_secondsinteger Minimum acceptable completion time. Triggers if completed faster (potential bot). max_secondsinteger Maximum acceptable completion time. Triggers if slower (abandoned/suspicious). actionstring ✓ Action 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
Property Type Description enabledboolean Enable email verification. Default: false providerstring Provider: zerobounce, neverbounce, hunter, internal. Default: internal
Rule Properties
Property Type Description on_invalidstring Action when email is invalid/does not exist. Default: auto_deny on_disposablestring Action when email is from disposable/temporary domain. Default: flag on_role_basedstring Action when email is role-based (info@, admin@). Default: flag on_unverifiablestring Action 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
Property Type Description face_match_thresholdnumber Threshold for face matching (0-1). Default: 0.85 face_match_action_on_failstring Action 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). Property Type Description min_scorenumber Minimum score to trigger (triggers if score >= min) max_scorenumber Maximum score to trigger (triggers if score < max) actionstring Action to trigger
Rules for SSL certificate validation. Property Type Description on_no_sslstring Action when site has no SSL. Default: ‘auto_deny’ on_invalid_sslstring Action when SSL is invalid/expired. Default: ‘manual_review’ min_days_until_expiryinteger Trigger if SSL expires within this many days expiry_actionstring Action when SSL is near expiry. Default: ‘flag’
Rules for specific page statuses. Status Description 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. Property Type Description blocked_industriesarray Industry names/IDs that trigger rule on_blockedstring Action when industry is blocked. Default: ‘auto_deny’ on_mismatchstring Action when detected industry doesn’t match declared. Default: ‘flag’ min_confidencenumber Minimum confidence for industry classification (0-1). Default: 0.7
Rules for domain sanction check. Property Type Description on_matchstring Action when domain found on sanction lists. Default: ‘auto_deny’ lists_to_checkarray Lists to check: ‘ofac’, ‘un’, ‘eu’, ‘uk’, ‘au’, ‘ca’, ‘world_bank’, etc.
Rules based on Tranco popularity ranking. Property Type Description on_not_rankedstring Action when site not in top 1M. Default: ‘flag’ min_rankinteger Trigger if rank is worse (higher number) band_actionsobject Actions per ranking band: ‘top_10k’, ‘top_100k’, ‘top_500k’, ‘top_1m’, ‘not_ranked’
Rules for page content evidence. Property Type Description on_unrealistic_promisesstring Action for scam-like promises. Default: ‘auto_deny’ on_no_contact_infostring Action for no contact info. Default: ‘flag’ on_no_real_productsstring Action for placeholder products. Default: ‘flag’ on_no_navigationstring Action for no functional navigation. Default: ‘flag’ require_phoneboolean Require phone number in contact require_emailboolean Require email in contact require_addressboolean Require physical address on_missing_required_contactstring Action 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
Property Type Description enabledboolean Enable watchlist auto-add feature. Default: true async_addboolean Add to watchlist asynchronously. Set false to get subject_ids (slower). Default: true deduplicateboolean Avoid adding same name twice from same session. Default: true return_subject_idsboolean If true, forces sync invocation to return subject_ids. Default: false
Rule Properties
Property Type Required Description trigger_onstring ✓ Session outcome: approved, rejected, flagged, manual_review watchlist_idstring ✓ Target watchlist ID to add subjects to ttl_daysinteger Override default TTL for subjects (days) tagsarray Additional tags to add to each subject include_automation_flagsboolean Add triggered automation rule flags as subject tags. Default: true include_entity_type_tagboolean Add entity type as tag. Default: true entity_typesarray Entity types: individual, company, ubo, director, shareholder, domain, wallet. Empty = all. enabledboolean Whether this rule is enabled. Default: true
Entity Types
Type Description 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:
Validation runs : Lists, adverse media, crypto, face match
Rules evaluated : All applicable rules are checked
Actions collected : All triggered actions are recorded
Final decision : Highest priority action determines outcome
Watchlist add : If configured, entities are added to watchlists
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" }
]
}
}
}
on_no_socialon_all_invalidmin_valid_linksrequired_platformson_missing_required