Skip to main content
The Email Verification feature emits warnings whenever a risk signal fires on the OTP flow or the address itself: a known data breach, a disposable provider, an undeliverable mailbox, an OTP attempt cap, or a hit against your blocklist or another approved verification. This page lists every code, what triggers it, and how to configure the workflow response.

Overview

Warnings are tagged with feature EMAIL. They appear on the report under email_verifications[].warnings[] and follow the standard warning object shape (feature, risk, additional_data, log_type, short_description, long_description, node_id). Each warning is also routed into the per-session log so it surfaces in the Business Console under the Email section. Some warnings are hard auto-decline triggers — they always set the feature status to Declined and carry log_type: "error". The others map to a configurable action (DECLINE, REVIEW, or the default NO_ACTION) defined per workflow node or per API call, so the same risk code may decline one workflow while only flagging another. The configured action also sets the severity: DECLINEerror, REVIEWwarning, NO_ACTIONinformation.

Auto-decline conditions

The following warnings always decline the Email Verification step regardless of configuration:
  • EMAIL_CODE_ATTEMPTS_EXCEEDED — the user exhausted the OTP budget: 2 wrong code entries (email_max_check_attempts) or 2 OTP sends — the initial send plus one resend (email_max_retries) — by default.
  • EMAIL_IN_BLOCKLIST — the address is in a blocklist managed via the Lists API, or matched a previously approved email verification that was blocklisted.
  • UNDELIVERABLE_EMAIL_DETECTED — the address cannot receive mail: invalid syntax, a non-existent domain, missing DNS (MX) records, or the OTP email could not be delivered. The step finalizes as Declined immediately — no code check ever runs. Exception: when the user typed the address themselves (it was not pre-filled at session creation), an undeliverable send returns an inline error so they can retry with a different address instead of being declined.

Configurable risks

Each of the following risks maps to a setting (per workflow node, or per call on the standalone check endpoint) you can configure to DECLINE, REVIEW, or NO_ACTION:
SettingRisk codeDefault behavior
breached_email_actionBREACHED_EMAIL_DETECTEDNO_ACTION — surface breach details at information level without changing the status.
disposable_email_actionDISPOSABLE_EMAIL_DETECTEDNO_ACTION — flag the throwaway provider at information level without changing the status.
duplicated_email_actionDUPLICATED_EMAILNO_ACTION — record the duplicate at information level. Skipped when the address is allowlisted.
Duplicate detection only considers previously approved email verifications in the same application, grouped by vendor_data — verifications sharing the same vendor_data are treated as one end-user and excluded. Leave vendor_data empty and every session is treated as a distinct user. If the address is on your email allowlist, the duplicate action is skipped and EMAIL_IN_ALLOWLIST is emitted instead.

Verification attempt limits

The Email Verification feature applies a hard cap on OTP attempts to prevent abuse:
  • Code-entry attemptsemail_max_check_attempts, default 2: the second wrong (or expired) code finalizes the step.
  • Send attemptsemail_max_retries, default 2 sends in total (the initial send plus one resend): a further resend request finalizes the step.
Exceeding either cap raises EMAIL_CODE_ATTEMPTS_EXCEEDED and auto-declines. You can tune both caps per workflow node.

Warnings produced

TagSeverityDescription
EMAIL_CODE_ATTEMPTS_EXCEEDEDerrorThe user exceeded the code-entry or send cap. Auto-declines.
EMAIL_IN_BLOCKLISTerrorThe address is present in a blocklist created via the Lists API, or matched a blocklisted approved verification. Auto-declines. additional_data carries blocklisted_session_id, blocklisted_session_number and api_service (all null for a pure list hit).
EMAIL_IN_ALLOWLISTinformationThe address matched an allowlist created via the Lists API, so the duplicate-email action was skipped.
BREACHED_EMAIL_DETECTEDPer breached_email_action (information by default)The address was found in one or more known data breaches. The breaches[] array on the report carries the breached service, date and data classes.
DISPOSABLE_EMAIL_DETECTEDPer disposable_email_action (information by default)The domain is a known disposable / throwaway provider often used to evade traceability.
UNDELIVERABLE_EMAIL_DETECTEDerrorThe address cannot receive mail (invalid syntax, non-existent domain, missing MX records, or failed delivery). Auto-declines.
DUPLICATED_EMAILPer duplicated_email_action (information by default)The address matches a previously approved email verification belonging to a different end-user (grouped by vendor_data). additional_data carries duplicated_session_id, duplicated_session_number and api_service.
At most one of EMAIL_IN_BLOCKLIST, DUPLICATED_EMAIL and EMAIL_IN_ALLOWLIST fires per attempt — blocklist takes precedence over duplicate, which takes precedence over allowlist.

Cross-session matches

When an address is detected on previously approved email verifications or on your blocklist, those hits also appear under email_verifications[].matches[] (capped at 5 entries). Each match carries session_id, session_number, vendor_data, verification_date, email, status, is_blocklisted, api_service, and a source of session (another approved verification) or list_entry (a blocklist entry). If the current address is on your email allowlist, Didit keeps the match evidence but emits EMAIL_IN_ALLOWLIST instead of applying the duplicate-email action. See the Email Verification report for the full match schema.

Example

{
  "warnings": [
    {
      "feature": "EMAIL",
      "risk": "EMAIL_IN_BLOCKLIST",
      "additional_data": {
        "blocklisted_session_id": null,
        "blocklisted_session_number": null,
        "api_service": null
      },
      "log_type": "error",
      "short_description": "Email in blocklist",
      "long_description": "The system detected that the email is in the blocklist, which is not allowed.",
      "node_id": "feature_email_1"
    },
    {
      "feature": "EMAIL",
      "risk": "DISPOSABLE_EMAIL_DETECTED",
      "additional_data": null,
      "log_type": "information",
      "short_description": "Disposable email detected",
      "long_description": "The system detected that the email is disposable, which is not allowed.",
      "node_id": "feature_email_1"
    }
  ]
}

Warning types

Each risk is assigned a severity based on your application’s configuration. Severities fall into three categories: