> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compliance.legaltalent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Automation Rules

> Configure automatic session decisions with country rules, list matches, face dedup, documents, and more

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.

```json theme={null}
{
  "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_approve`  | Automatically approve the session         | Session status → `approved`                             |
| `auto_deny`     | Automatically reject the session          | Session status → `rejected`                             |
| `manual_review` | Require human review                      | Session status → `manual_review`                        |
| `flag`          | Approve but mark for attention/monitoring | Session status → `approved`, final decision → `flagged` |
| `no_action`     | No action taken                           | Continue processing                                     |

<Note>
  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.
</Note>

## Base Configuration

| Property         | Type    | Description                                                                                                  |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------ |
| `enabled`        | boolean | Enable automation rules processing (default: true)                                                           |
| `auto_process`   | boolean | Automatically process session when all steps are completed. No manual POST /process needed. (default: false) |
| `default_action` | string  | 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.

```json theme={null}
{
  "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_code` | string | ✓        | ISO 3166-1 alpha-2 country code (e.g., `US`, `KP`, `IR`)                                                                                            |
| `action`       | string | ✓        | Action to trigger: `auto_approve`, `auto_deny`, `manual_review`, `flag`, `no_action`                                                                |
| `applies_to`   | array  |          | Country field types: `nationality`, `residence`, `incorporation`, `tax_residence`, `birth_country`, `business_operation`, `all`. Default: `["all"]` |
| `reason`       | string |          | Reason 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)

<Tip>
  Use `applies_to` to differentiate between nationality and residence rules. A user with `nationality: IR` and `residence: US` can have different rules applied.
</Tip>

***

## List Match Rules

Trigger actions based on sanctions/watchlist matches.

```json theme={null}
{
  "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_type`    | string |          | List type: `any`, `ofac`, `un`, `eu`, `uk`, `au`, `ca`, `pep`, `adverse_media`. Default: `any` |
| `match_level`  | string |          | Confidence level: `any`, `high_confidence`, `exact`. Default: `any`                            |
| `entity_scope` | string |          | Apply to: `primary`, `related_parties`, `all`. Default: `all`                                  |
| `action`       | string | ✓        | Action to trigger                                                                              |

### Entity Scope

| Scope             | Description                                                            |
| ----------------- | ---------------------------------------------------------------------- |
| `primary`         | Only the main individual/company being onboarded                       |
| `related_parties` | Directors, shareholders, beneficial owners (from entity\_array fields) |
| `all`             | Both primary subject and related parties                               |

<Warning>
  If you have different risk appetite for directors vs the primary subject, use multiple rules with different `entity_scope` values.
</Warning>

***

## Face Deduplication

Detect repeat applicants by comparing faces across sessions.

### Configuration

```json theme={null}
{
  "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                                                            |
| ---------------------- | ------- | ---------------------------------------------------------------------- |
| `enabled`              | boolean | Enable face deduplication (default: false)                             |
| `auto_add_to_index`    | boolean | Automatically add new faces to the deduplication index (default: true) |
| `similarity_threshold` | number  | Threshold to consider faces as same person (0-1). Default: 0.92        |

### Rule Properties

| Property                | Type    | Required | Description                                              |
| ----------------------- | ------- | -------- | -------------------------------------------------------- |
| `min_previous_sessions` | integer | ✓        | Minimum number of previous sessions to trigger rule (≥1) |
| `include_approved`      | boolean |          | Count approved sessions (default: true)                  |
| `include_rejected`      | boolean |          | Count rejected sessions (default: true)                  |
| `include_pending`       | boolean |          | Count pending/processing sessions (default: false)       |
| `action`                | string  | ✓        | 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.

```json theme={null}
{
  "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_types`           | array   | Document types: `id`, `passport`, `proof_of_address`, `all`. Default: `["all"]` |
| `max_days_until_expiry`    | integer | Trigger if document expires within this many days                               |
| `expiry_action`            | string  | Action when document is near expiry. Default: `flag`                            |
| `min_days_since_issue`     | integer | Trigger if document was issued less than this many days ago (too new)           |
| `max_days_since_issue`     | integer | Trigger if document was issued more than this many days ago (too old)           |
| `age_action`               | string  | Action for document age violations. Default: `flag`                             |
| `expired_action`           | string  | Action when document is already expired. Default: `auto_deny`                   |
| `reject_invalid_documents` | boolean | Reject documents where is\_valid\_document=false. Default: true                 |
| `invalid_document_action`  | string  | Action when document type doesn't match expected. Default: `auto_deny`          |
| `min_image_quality`        | string  | Minimum quality: `excellent`, `good`, `acceptable`                              |
| `poor_quality_action`      | string  | Action when image quality is below threshold. Default: `manual_review`          |

### Document Validation Checks

| Check                   | Description                                            |
| ----------------------- | ------------------------------------------------------ |
| `max_days_until_expiry` | Document expires soon (e.g., within 90 days)           |
| `expired`               | Document is already expired                            |
| `min_days_since_issue`  | Document was issued too recently (possible fraud)      |
| `max_days_since_issue`  | Document is too old (e.g., proof of address > 90 days) |
| `is_valid_document`     | Document type matches expected (not a pet photo)       |
| `image_quality`         | Image is clear, readable, properly lit                 |

***

## Extraction Validation Rules

Run additional validations on fields extracted from documents.

```json theme={null}
{
  "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_id`                             | string |          | Unique identifier for this rule                                                   |
| `description`                         | string |          | Human-readable description                                                        |
| `extracted_field`                     | string | ✓        | Name of extracted field to validate (e.g., `full_name`, `company_name`, `tax_id`) |
| `from_document_types`                 | array  |          | Only apply to these document types. Default: `["all"]`                            |
| `validations`                         | array  | ✓        | List of validation types to run                                                   |
| `cross_validate_with_field`           | string |          | Form field\_id to compare against (for cross\_validate\_form)                     |
| `cross_validate_similarity_threshold` | number |          | Minimum similarity score for cross-validation (0-1). Default: 0.8                 |
| `custom_validation_lambda`            | string |          | Lambda function ARN for custom validation                                         |
| `action_on_match`                     | string |          | Action when validation finds an issue. Default: `manual_review`                   |
| `action_on_mismatch`                  | string |          | Action when cross-validation fails. Default: `flag`                               |
| `action_on_error`                     | string |          | Action when validation service fails. Default: `flag`                             |

### Validation Types

| Type                  | Description                       |
| --------------------- | --------------------------------- |
| `sanctions_lists`     | Check against OFAC, UN, EU lists  |
| `adverse_media`       | News/media screening              |
| `cross_validate_form` | Compare with form data            |
| `pep_check`           | Politically Exposed Persons check |
| `company_registry`    | Company registration lookup       |
| `tax_registry`        | Tax ID validation                 |
| `custom`              | Custom validation Lambda          |

***

## Form Field Rules

Trigger actions based on user-declared form field values.

```json theme={null}
{
  "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_id` | string | ✓        | The field\_id of the form field to evaluate                                                                     |
| `operator` | string | ✓        | Comparison operator (see table below)                                                                           |
| `value`    | any    |          | Value or list of values to compare against (not required for `is_true`, `is_false`, `is_empty`, `is_not_empty`) |
| `action`   | string | ✓        | Action to trigger when condition is met                                                                         |
| `reason`   | string |          | Human-readable reason (for audit trail and UI)                                                                  |

### Operators

| Operator       | Description            | Value Required |
| -------------- | ---------------------- | -------------- |
| `equals`       | Exact match            | Yes            |
| `not_equals`   | Not equal              | Yes            |
| `in`           | Value is in list       | Yes (array)    |
| `not_in`       | Value is not in list   | Yes (array)    |
| `contains`     | String contains        | Yes            |
| `not_contains` | String doesn't contain | Yes            |
| `is_true`      | Boolean is true        | No             |
| `is_false`     | Boolean is false       | No             |
| `is_empty`     | Field is empty/null    | No             |
| `is_not_empty` | Field has value        | No             |
| `gt`           | Greater than           | Yes            |
| `lt`           | Less than              | Yes            |
| `gte`          | Greater than or equal  | Yes            |
| `lte`          | Less than or equal     | Yes            |

***

## Volume Rules

Trigger actions based on declared transaction volume.

```json theme={null}
{
  "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_volume`       | number |          | Minimum monthly volume in USD to trigger (if above) |
| `max_monthly_volume`       | number |          | Maximum monthly volume in USD to trigger (if below) |
| `min_monthly_transactions` | number |          | Minimum monthly transaction count to trigger        |
| `max_monthly_transactions` | number |          | Maximum monthly transaction count to trigger        |
| `action`                   | string | ✓        | Action to trigger                                   |

<Note>
  Volume rules apply to `volume` fields and `currency` fields with `apply_volume_rules: true`.
</Note>

***

## Time to Complete Rules

Trigger actions based on how long the session took to complete.

```json theme={null}
{
  "time_to_complete_rules": [
    {
      "min_seconds": 30,
      "action": "flag"
    },
    {
      "max_seconds": 86400,
      "action": "flag"
    }
  ]
}
```

### Properties

| Property      | Type    | Required | Description                                                                       |
| ------------- | ------- | -------- | --------------------------------------------------------------------------------- |
| `min_seconds` | integer |          | Minimum acceptable completion time. Triggers if completed faster (potential bot). |
| `max_seconds` | integer |          | Maximum acceptable completion time. Triggers if slower (abandoned/suspicious).    |
| `action`      | string  | ✓        | 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.

```json theme={null}
{
  "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                                                                      |
| ---------- | ------- | -------------------------------------------------------------------------------- |
| `enabled`  | boolean | Enable email verification. Default: false                                        |
| `provider` | string  | Provider: `zerobounce`, `neverbounce`, `hunter`, `internal`. Default: `internal` |

### Rule Properties

| Property          | Type   | Description                                                              |
| ----------------- | ------ | ------------------------------------------------------------------------ |
| `on_invalid`      | string | Action when email is invalid/does not exist. Default: `auto_deny`        |
| `on_disposable`   | string | Action when email is from disposable/temporary domain. Default: `flag`   |
| `on_role_based`   | string | Action when email is role-based (info@, admin@). Default: `flag`         |
| `on_unverifiable` | string | Action when email cannot be verified (catch-all domain). Default: `flag` |

***

## Face Match Rules

Configure face matching between ID photo and selfie/liveness.

```json theme={null}
{
  "face_match_threshold": 0.85,
  "face_match_action_on_fail": "auto_deny"
}
```

### Properties

| Property                    | Type   | Description                                        |
| --------------------------- | ------ | -------------------------------------------------- |
| `face_match_threshold`      | number | Threshold for face matching (0-1). Default: 0.85   |
| `face_match_action_on_fail` | string | Action when face match fails. Default: `auto_deny` |

***

## Web Validation Rules

Comprehensive rules for website/domain validation. See [Web Validation](/api-reference/web-validation) for background.

```json theme={null}
{
  "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
    },
    
    "policy_rules": {
      "terms_rules": {
        "on_not_found": "flag",
        "on_generic_format": "manual_review",
        "require_rut": true,
        "on_missing_rut": "manual_review",
        "validate_rut_against_declared": true,
        "on_rut_mismatch": "manual_review"
      },
      "aml_rules": {
        "on_not_found": "flag",
        "on_generic_format": "manual_review"
      },
      "return_rules": {
        "on_not_found": "flag"
      },
      "refund_rules": {
        "on_not_found": "flag"
      }
    }
  }
}
```

### Rule Components

<Accordion title="Score Rules">
  Trigger actions based on overall reliability score (0-100).

  | Property    | Type   | Description                                         |
  | ----------- | ------ | --------------------------------------------------- |
  | `min_score` | number | Minimum score to trigger (triggers if score >= min) |
  | `max_score` | number | Maximum score to trigger (triggers if score \< max) |
  | `action`    | string | Action to trigger                                   |
</Accordion>

<Accordion title="SSL Rules">
  Rules for SSL certificate validation.

  | Property                | Type    | Description                                                   |
  | ----------------------- | ------- | ------------------------------------------------------------- |
  | `on_no_ssl`             | string  | Action when site has no SSL. Default: 'auto\_deny'            |
  | `on_invalid_ssl`        | string  | Action when SSL is invalid/expired. Default: 'manual\_review' |
  | `min_days_until_expiry` | integer | Trigger if SSL expires within this many days                  |
  | `expiry_action`         | string  | Action when SSL is near expiry. Default: 'flag'               |
</Accordion>

<Accordion title="Page Status Rules">
  Rules for specific page statuses.

  | Status                | Description                   |
  | --------------------- | ----------------------------- |
  | `INCOMPLETE_TEMPLATE` | Site appears to be a template |
  | `UNDER_CONSTRUCTION`  | Under construction page       |
  | `DOWN`                | Site is down                  |
  | `MAINTENANCE`         | Maintenance mode              |
  | `NOT_AVAILABLE`       | Not available                 |
  | `GEO_RESTRICTED`      | Geographically restricted     |
</Accordion>

<Accordion title="Industry Rules">
  Rules for industry classification.

  | Property             | Type   | Description                                                                                     |
  | -------------------- | ------ | ----------------------------------------------------------------------------------------------- |
  | `blocked_industries` | array  | Industry names/IDs that trigger rule                                                            |
  | `on_blocked`         | string | Action when industry is blocked (not allowed). Default: `auto_deny`                             |
  | `on_flagged`         | string | Action when industry is flagged (allowed but requires extra scrutiny). Default: `manual_review` |
  | `on_mismatch`        | string | Action when detected industry doesn't match declared. Default: `flag`                           |
  | `min_confidence`     | number | 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.
</Accordion>

<Accordion title="Adverse Media Rules">
  Rules for adverse media check results.

  | Property         | Type   | Description                                                         |
  | ---------------- | ------ | ------------------------------------------------------------------- |
  | `on_high_risk`   | string | Action for HIGH\_RISK decision (76-100). Default: 'auto\_deny'      |
  | `on_medium_risk` | string | Action for MEDIUM\_RISK decision (51-75). Default: 'manual\_review' |
  | `on_low_risk`    | string | Action for LOW\_RISK decision (26-50). Default: 'flag'              |
  | `min_risk_score` | number | Custom threshold: trigger if adverse media risk >= value            |
  | `custom_action`  | string | Action for custom min\_risk\_score threshold                        |
</Accordion>

<Accordion title="Sanction Rules">
  Rules for domain sanction check.

  | Property         | Type   | Description                                                               |
  | ---------------- | ------ | ------------------------------------------------------------------------- |
  | `on_match`       | string | Action when domain found on sanction lists. Default: 'auto\_deny'         |
  | `lists_to_check` | array  | Lists to check: 'ofac', 'un', 'eu', 'uk', 'au', 'ca', 'world\_bank', etc. |
</Accordion>

<Accordion title="Social Media Rules">
  Rules for social media presence.

  | Property              | Type    | Description                                                         |
  | --------------------- | ------- | ------------------------------------------------------------------- |
  | `on_no_social`        | string  | Action when no social links found. Default: 'flag'                  |
  | `on_all_invalid`      | string  | Action when all social links are invalid. Default: 'manual\_review' |
  | `min_valid_links`     | integer | Minimum valid social links required. Default: 1                     |
  | `required_platforms`  | array   | Platforms that must be present                                      |
  | `on_missing_required` | string  | Action when required platform missing. Default: 'flag'              |
</Accordion>

<Accordion title="Tranco Rules">
  Rules based on Tranco popularity ranking.

  | Property        | Type    | Description                                                                              |
  | --------------- | ------- | ---------------------------------------------------------------------------------------- |
  | `on_not_ranked` | string  | Action when site not in top 1M. Default: 'flag'                                          |
  | `min_rank`      | integer | Trigger if rank is worse (higher number)                                                 |
  | `band_actions`  | object  | Actions per ranking band: 'top\_10k', 'top\_100k', 'top\_500k', 'top\_1m', 'not\_ranked' |
</Accordion>

<Accordion title="Page Evidence Rules">
  Rules for page content evidence.

  | Property                      | Type    | Description                                           |
  | ----------------------------- | ------- | ----------------------------------------------------- |
  | `on_unrealistic_promises`     | string  | Action for scam-like promises. Default: 'auto\_deny'  |
  | `on_no_contact_info`          | string  | Action for no contact info. Default: 'flag'           |
  | `on_no_real_products`         | string  | Action for placeholder products. Default: 'flag'      |
  | `on_no_navigation`            | string  | Action for no functional navigation. Default: 'flag'  |
  | `require_phone`               | boolean | Require phone number in contact                       |
  | `require_email`               | boolean | Require email in contact                              |
  | `require_address`             | boolean | Require physical address                              |
  | `on_missing_required_contact` | string  | Action when required contact missing. Default: 'flag' |
</Accordion>

<Accordion title="Policy Rules">
  Rules for website policy analysis: Terms & Conditions (`terms_rules`), AML/KYC policy (`aml_rules`), return policy (`return_rules`), and refund policy (`refund_rules`). Each policy triggers rules of type `web_policy_terms`, `web_policy_aml`, `web_policy_return`, `web_policy_refund` respectively.

  Common properties (all four policy types):

  | Property            | Type   | Description                                                               |
  | ------------------- | ------ | ------------------------------------------------------------------------- |
  | `on_not_found`      | string | Action when the policy is not found on the site. Default: 'flag'          |
  | `on_generic_format` | string | Action when the policy uses a generic template. Default: 'manual\_review' |

  Additional properties for `terms_rules` and `aml_rules`:

  | Property                | Type    | Description                                               |
  | ----------------------- | ------- | --------------------------------------------------------- |
  | `require_rut`           | boolean | Require company RUT/tax ID in the policy                  |
  | `on_missing_rut`        | string  | Action when RUT/tax ID missing. Default: 'manual\_review' |
  | `require_legal_name`    | boolean | Require legal company name                                |
  | `on_missing_legal_name` | string  | Action when legal name missing. Default: 'flag'           |

  `terms_rules` only:

  | Property                        | Type    | Description                                                                  |
  | ------------------------------- | ------- | ---------------------------------------------------------------------------- |
  | `require_address`               | boolean | Require company address in TyC                                               |
  | `on_missing_address`            | string  | Action when address missing. Default: 'flag'                                 |
  | `on_missing_is_of_age`          | string  | Action when age clause missing. Default: 'flag'                              |
  | `on_missing_applicable_law`     | string  | Action when applicable law clause missing. Default: 'flag'                   |
  | `on_missing_dos_clause`         | string  | Action when denial-of-service clause missing. Default: 'flag'                |
  | `on_missing_termination_clause` | string  | Action when termination clause missing. Default: 'flag'                      |
  | `on_missing_privacy_policy`     | string  | Action when privacy clause missing. Default: 'flag'                          |
  | `validate_rut_against_declared` | boolean | Compare TyC RUT against the tax ID declared in the session                   |
  | `on_rut_mismatch`               | string  | Action when TyC RUT doesn't match declared tax ID. Default: 'manual\_review' |

  `aml_rules` only:

  | Property                            | Type   | Description                                                        |
  | ----------------------------------- | ------ | ------------------------------------------------------------------ |
  | `on_missing_sanction_screening`     | string | Action when sanctions screening clause missing. Default: 'flag'    |
  | `on_missing_pep_screening`          | string | Action when PEP screening clause missing. Default: 'flag'          |
  | `on_missing_transaction_monitoring` | string | Action when transaction monitoring clause missing. Default: 'flag' |
  | `on_missing_risk_based_approach`    | string | Action when risk-based approach clause missing. Default: 'flag'    |
</Accordion>

***

## Watchlist Auto-Add

Automatically add entities to watchlists based on session outcome.

```json theme={null}
{
  "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                                                                            |
| -------------------- | ------- | -------------------------------------------------------------------------------------- |
| `enabled`            | boolean | Enable watchlist auto-add feature. Default: true                                       |
| `async_add`          | boolean | Add to watchlist asynchronously. Set false to get subject\_ids (slower). Default: true |
| `deduplicate`        | boolean | Avoid adding same name twice from same session. Default: true                          |
| `return_subject_ids` | boolean | If true, forces sync invocation to return subject\_ids. Default: false                 |

### Rule Properties

| Property                   | Type    | Required | Description                                                                                               |
| -------------------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `trigger_on`               | string  | ✓        | Session outcome: `approved`, `rejected`, `flagged`, `manual_review`                                       |
| `watchlist_id`             | string  | ✓        | Target watchlist ID to add subjects to                                                                    |
| `ttl_days`                 | integer |          | Override default TTL for subjects (days)                                                                  |
| `tags`                     | array   |          | Additional tags to add to each subject                                                                    |
| `include_automation_flags` | boolean |          | Add triggered automation rule flags as subject tags. Default: true                                        |
| `include_entity_type_tag`  | boolean |          | Add entity type as tag. Default: true                                                                     |
| `entity_types`             | array   |          | Entity types: `individual`, `company`, `ubo`, `director`, `shareholder`, `domain`, `wallet`. Empty = all. |
| `enabled`                  | boolean |          | Whether this rule is enabled. Default: true                                                               |

### Entity Types

| Type          | Description                |
| ------------- | -------------------------- |
| `individual`  | Primary individual subject |
| `company`     | Primary company subject    |
| `ubo`         | Ultimate beneficial owners |
| `director`    | Company directors          |
| `shareholder` | Shareholders               |
| `domain`      | Website domains            |
| `wallet`      | Crypto wallet addresses    |

***

## Complete Example

```json theme={null}
{
  "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. **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)
6. **Watchlist add**: If configured, entities are added to watchlists
7. **Response returned**: Includes `automation_flags` and `final_decision`

### Response with Automation Results

```json theme={null}
{
  "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"}
      ]
    }
  }
}
```

## Related Documentation

* [Workflows Overview](/api-reference/workflows) - Creating workflows
* [Field Types](/api-reference/workflows/fields) - Semantic fields that integrate with rules
* [Sessions](/api-reference/sessions) - Processing sessions
* [Web Validation](/api-reference/web-validation) - Website validation details
