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 flagApprove but mark for attention/monitoring Session status → approved, final decision → flagged 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. The flag action results in a flagged final decision. Flagged sessions are considered approved (the session status is approved) but are marked for extra attention or monitoring. This is useful for industries or conditions that don’t warrant rejection but require oversight.
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_flagged" : "manual_review" ,
"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 (not allowed). Default: auto_deny on_flaggedstring Action when industry is flagged (allowed but requires extra scrutiny). Default: manual_review on_mismatchstring Action when detected industry doesn’t match declared. Default: flag min_confidencenumber Minimum confidence for industry classification (0-1). Default: 0.7
Evaluation priority: blocked industries are checked first, then flagged industries, then industry mismatch. A blocked industry will not also trigger the flagged rule.
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
Status mapping : The final decision maps to a session status:
auto_approve → approved
auto_deny → rejected
flag → approved (with final_decision = flagged)
manual_review → manual_review
no_action → manual_review (default for safety)
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