Overview
Warnings are tagged with featurePHONE. They appear under phone_verifications[].warnings[] in GET /v3/session/{sessionId}/decision/ 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 Phone section.
Some warnings are hard auto-decline triggers — they always set the feature status to Declined. Others map to a configurable action (DECLINE, REVIEW, or NO_ACTION) defined in your workflow settings, so the same risk code may decline one workflow while only flagging another.
Auto-decline conditions
The following warnings always decline the Phone Verification step regardless of configuration, and always carrylog_type: "error":
VERIFICATION_CODE_ATTEMPTS_EXCEEDED— the user exhausted an OTP attempt cap: by default 2 wrong code submissions (phone_max_check_attempts) or more than 2 OTP sends (phone_max_retries), both tunable per workflow node. The standalone phone API allows 3 code attempts.PHONE_NUMBER_IN_BLOCKLIST— the number is in your blocklist managed via the Lists API, or it matches a blocklisted session.HIGH_RISK_PHONE_NUMBER— the delivery provider’s anti-fraud layer refused to send the OTP (Blockedsend). The blocking reason (repeated_attempts,suspicious, orspam) is returned inadditional_data.blocked_reason.
Configurable risks
Each of the following risks maps to a workflow setting you can configure toDECLINE, REVIEW, or NO_ACTION (the default — the warning is recorded without affecting the status). The configured action also sets the warning’s log_type: DECLINE → error, REVIEW → warning, NO_ACTION → information.
| Setting | Risk code | Fires when |
|---|---|---|
voip_number_action | VOIP_NUMBER_DETECTED | The carrier resolves to a voip, isp, or vpn line type. |
disposable_number_action | DISPOSABLE_NUMBER_DETECTED | The lookup flags the number as a temporary / burner provider. |
duplicated_phone_number_action | DUPLICATED_PHONE_NUMBER | The number matches another session of any status belonging to a different end-user. Skipped when the number is allowlisted. |
vendor_data — sessions sharing the same vendor_data are treated as one end-user and are excluded from match results. Leave vendor_data empty and every session is treated as a distinct user.
Verification attempt limits
The Phone Verification feature applies a hard cap on OTP attempts to prevent abuse:- Code-entry attempts — Default 2 wrong submissions (
phone_max_check_attempts) before the step finalizes asDeclinedwithVERIFICATION_CODE_ATTEMPTS_EXCEEDED. The standalone phone API allows 3 code attempts per verification. - Send attempts — Default 2 sends in total (
phone_max_retries): the initial send plus one resend. A further send request finalizes the step and raisesVERIFICATION_CODE_ATTEMPTS_EXCEEDED. - OTP validity — A pending OTP is valid for 5 minutes from the first send; retries do not extend the window.
repeated_attempts, suspicious, or spam) — that raises HIGH_RISK_PHONE_NUMBER, not the attempts warning.
Warnings produced
| Tag | log_type | Description |
|---|---|---|
VERIFICATION_CODE_ATTEMPTS_EXCEEDED | error (always) | The user exceeded the OTP code-entry or send cap. Auto-declines. |
HIGH_RISK_PHONE_NUMBER | error (always) | The delivery provider blocked the OTP send. Auto-declines. additional_data: { blocked_reason }. |
PHONE_NUMBER_IN_BLOCKLIST | error (always) | The number is in a blocklist created via the Lists API, or matches a blocklisted session. Auto-declines. additional_data: { blocklisted_session_id, blocklisted_session_number, api_service } (all null for a pure list hit). |
PHONE_NUMBER_IN_ALLOWLIST | information | The number matched other sessions but is in an allowlist created via the Lists API, so duplicate-phone actions are skipped. additional_data: { phone_number }. |
DISPOSABLE_NUMBER_DETECTED | Follows disposable_number_action | The number is a temporary / burner provider often used to evade traceability. |
VOIP_NUMBER_DETECTED | Follows voip_number_action | The number resolves to a voip, isp, or vpn line rather than a standard mobile or fixed line. |
DUPLICATED_PHONE_NUMBER | Follows duplicated_phone_number_action | The number matches another session — of any status — belonging to a different end-user (grouped by vendor_data). additional_data: { duplicated_session_id, duplicated_session_number, api_service }. |
Cross-session matches
When a number is detected on other sessions or on your blocklist, those hits also appear underphone_verifications[].matches[] (capped at 5 entries). Each match carries session_id, session_number, vendor_data, verification_date, phone_number, status, is_blocklisted, api_service, and a source of session (another session with the same number, any status) or list_entry (a synthetic blocklist hit prepended to the array). If the current number is on your phone allowlist, Didit keeps the match evidence but emits PHONE_NUMBER_IN_ALLOWLIST instead of applying the duplicate-phone action. See the Phone Verification report for the full match schema.
Example
A blocked send (HIGH_RISK_PHONE_NUMBER) on a VoIP number, with voip_number_action configured to REVIEW:
Warning types
Each risk is assigned a severity based on your application’s configuration. Severities fall into three categories:Related
- Phone Verification overview — feature behavior, pricing, supported channels.
- Phone Verification report — full response shape including
lifecycle[]andmatches[]. - Data models — phone verification — canonical field-by-field schema.
- Management API — Lists — manage the phone blocklist used by
PHONE_NUMBER_IN_BLOCKLIST.