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, depending on the setting) 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 refusing to send the OTP (Blocked send) — declines by default but is no longer unconditional: see high_risk_phone_action below.
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.
Duplicate detection runs within your application across KYC, KYB, and standalone API phone verifications, and groups sessions by
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.
Blocked sends
HIGH_RISK_PHONE_NUMBER follows the same pattern with a narrower choice set, because a send the provider refused cannot be approved:
The setting is applied only when every high-risk block on the step carries
additional_data.risk_factors of exactly ["device_attribute"] — the provider’s “this device looks suspicious” signal, which is what fires on ordinary mobile lines. Any other risk factor, any mix that merely includes device_attribute, or a block with no risk factors at all declines regardless of the setting. The blocking reason (repeated_attempts, suspicious, or spam) is a separate field, returned in additional_data.blocked_reason.
Independently of the setting, a number on a phone allowlist created via the Lists API is never auto-declined for a blocked send: the step goes to In Review, the warning carries log_type: "warning", and additional_data.phone_number_in_allowlist is true.
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
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.