didit-email-verification

Integrate Didit Email Verification standalone API to verify email addresses via OTP. Use when the user wants to verify emails, send email OTP codes, check email verification codes, detect breached or disposable emails, check if an email is undeliverable, or implement email-based identity verification using Didit. Supports fraud signals (IP, device, user agent), configurable code length, alphanumeric codes, and policy-based auto-decline for risky emails.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "didit-email-verification" with this command: npx skills add didit-protocol/skills/didit-protocol-skills-didit-email-verification

Didit Email Verification API

Overview

Two-step email verification via one-time code:

  1. Send a verification code to an email address
  2. Check the code the user provides

Key constraints:

  • Code expires after 5 minutes
  • Maximum 3 verification attempts per code (then must resend)
  • Maximum 2 resend requests within 24 hours
  • You must call Send before Check — Check returns "Expired or Not Found" otherwise

Capabilities: Detects breached emails (via known data breaches), disposable/temporary email providers, and undeliverable addresses. Supports fraud signals for risk scoring.

API Reference: Send Code | Check Code Feature Guide: https://docs.didit.me/core-technology/email-verification/overview


Authentication

All requests require an API key via the x-api-key header.

How to obtain: Didit Business Console → API & Webhooks → Copy API key, or via programmatic registration (see below).

x-api-key: your_api_key_here

401 = API key missing or invalid. 403 = key lacks permissions or insufficient credits.

Getting Started (No Account Yet?)

If you don't have a Didit API key, create one in 2 API calls:

  1. Register: POST https://apx.didit.me/auth/v2/programmatic/register/ with {"email": "you@gmail.com", "password": "MyStr0ng!Pass"}
  2. Check email for a 6-character OTP code
  3. Verify: POST https://apx.didit.me/auth/v2/programmatic/verify-email/ with {"email": "you@gmail.com", "code": "A3K9F2"} → response includes api_key

To add credits: GET /v3/billing/balance/ to check, POST /v3/billing/top-up/ with {"amount_in_dollars": 50} for a Stripe checkout link.

See the didit-verification-management skill for full platform management (workflows, sessions, users, billing).


Step 1: Send Email Code

Sends a one-time verification code to the specified email address.

Request

POST https://verification.didit.me/v3/email/send/

Headers

HeaderValueRequired
x-api-keyYour API keyYes
Content-Typeapplication/jsonYes

Body (JSON)

ParameterTypeRequiredDefaultConstraintsDescription
emailstringYesValid emailEmail address to send code to
options.code_sizeintegerNo6Min: 4, Max: 8Length of the verification code
options.alphanumeric_codebooleanNofalsetrue = A-Z + 0-9 (case-insensitive)
options.localestringNoMax 5 charsLocale for email template. e.g. en-US
signals.ipstringNoIPv4 or IPv6User's IP for fraud detection
signals.device_idstringNoMax 255 charsUnique device identifier
signals.user_agentstringNoMax 512 charsBrowser/client user agent
vendor_datastringNoYour identifier for session tracking

Example

import requests

response = requests.post(
    "https://verification.didit.me/v3/email/send/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "email": "user@example.com",
        "options": {"code_size": 6},
        "signals": {"ip": "203.0.113.42"},
        "vendor_data": "session-abc-123",
    },
)
print(response.status_code, response.json())
const response = await fetch("https://verification.didit.me/v3/email/send/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    options: { code_size: 6 },
    signals: { ip: "203.0.113.42" },
  }),
});

Response (200 OK)

{
  "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
  "status": "Success",
  "reason": null
}

Status Values & Handling

StatusMeaningAction
"Success"Code sentProceed — wait for user to provide code, then call Check
"Retry"Temporary delivery issueWait a few seconds and retry Send (max 2 retries)
"Undeliverable"Email cannot receive mailInform user the email is invalid or cannot receive messages

Error Responses

CodeMeaningAction
400Invalid request body or emailCheck email format and parameter constraints
401Invalid or missing API keyVerify x-api-key header
403Insufficient credits/permissionsCheck credits in Business Console
429Rate limitedBack off and retry after indicated period

Step 2: Check Email Code

Verifies the code the user received. Must be called after a successful Send. Optionally auto-declines risky emails.

Request

POST https://verification.didit.me/v3/email/check/

Headers

HeaderValueRequired
x-api-keyYour API keyYes
Content-Typeapplication/jsonYes

Body (JSON)

ParameterTypeRequiredDefaultValuesDescription
emailstringYesValid emailSame email used in Step 1
codestringYes4-8 charsThe code the user received
duplicated_email_actionstringNo"NO_ACTION""NO_ACTION" / "DECLINE"Decline if email already verified by another user
breached_email_actionstringNo"NO_ACTION""NO_ACTION" / "DECLINE"Decline if email found in data breaches
disposable_email_actionstringNo"NO_ACTION""NO_ACTION" / "DECLINE"Decline if email is disposable/temporary
undeliverable_email_actionstringNo"NO_ACTION""NO_ACTION" / "DECLINE"Decline if email is undeliverable

Policy note: When an action is "DECLINE", verification is rejected even if the code is correct. The email.* fields are still populated so you can inspect why.

Example

response = requests.post(
    "https://verification.didit.me/v3/email/check/",
    headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json={
        "email": "user@example.com",
        "code": "123456",
        "breached_email_action": "DECLINE",
        "disposable_email_action": "DECLINE",
    },
)
const response = await fetch("https://verification.didit.me/v3/email/check/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    email: "user@example.com",
    code: "123456",
    breached_email_action: "DECLINE",
    disposable_email_action: "DECLINE",
  }),
});

Response (200 OK)

{
  "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
  "status": "Approved",
  "message": "The verification code is correct.",
  "email": {
    "status": "Approved",
    "email": "user@example.com",
    "is_breached": false,
    "breaches": [],
    "is_disposable": false,
    "is_undeliverable": false,
    "verification_attempts": 1,
    "verified_at": "2025-09-15T17:36:19.963451Z",
    "warnings": [],
    "lifecycle": [
      {"type": "EMAIL_VERIFICATION_MESSAGE_SENT", "timestamp": "...", "fee": 0.03},
      {"type": "VALID_CODE_ENTERED", "timestamp": "...", "fee": 0}
    ]
  },
  "created_at": "2025-09-15T17:36:19.703719+00:00"
}

Status Values & Handling

StatusMeaningAction
"Approved"Code correct, no policy violationsEmail verified — proceed with your flow
"Failed"Code incorrectAsk user to re-enter. After 3 failures, resend a new code
"Declined"Code correct but policy violationInform user. Check email.warnings for reason
"Expired or Not Found"No pending codeCode expired (>5 min) or Send was never called. Resend

Error Responses

CodeMeaningAction
400Invalid request bodyCheck email and code format
401Invalid or missing API keyVerify x-api-key header
403Insufficient credits/permissionsCheck credits in Business Console
404Code expired or not foundResend a new code via Step 1

Response Field Reference

email Object

FieldTypeDescription
statusstring"Approved", "Failed", "Declined"
emailstringThe email address verified
is_breachedbooleanFound in known data breaches
breachesarrayBreach details: {name, domain, breach_date, data_classes, breach_emails_count}
is_disposablebooleanFrom a disposable/temporary provider
is_undeliverablebooleanCannot receive email
verification_attemptsintegerNumber of check attempts (max 3)
verified_atstringISO 8601 timestamp when verified (null if not)
warningsarrayRisk warnings: {risk, log_type, short_description, long_description}
lifecyclearrayEvent log: {type, timestamp, fee}

Warning Tags

TagDescriptionAuto-Decline
EMAIL_CODE_ATTEMPTS_EXCEEDEDMax code entry attempts exceededYes
EMAIL_IN_BLOCKLISTEmail is in blocklistYes
UNDELIVERABLE_EMAIL_DETECTEDEmail cannot be deliveredYes
BREACHED_EMAIL_DETECTEDFound in known data breachesConfigurable
DISPOSABLE_EMAIL_DETECTEDDisposable/temporary providerConfigurable
DUPLICATED_EMAILAlready verified by another userConfigurable

Warning severity levels: error (critical), warning (requires attention), information (informational).


Common Workflows

Basic Email Verification

1. POST /v3/email/send/   → {"email": "user@example.com"}
2. Wait for user to provide the code
3. POST /v3/email/check/  → {"email": "user@example.com", "code": "123456"}
4. If "Approved"            → email is verified
   If "Failed"              → ask user to retry (up to 3 attempts)
   If "Expired or Not Found"→ go back to step 1

Strict Security Verification

1. POST /v3/email/send/   → include signals.ip, signals.device_id, signals.user_agent
2. Wait for user to provide the code
3. POST /v3/email/check/  → set all *_action fields to "DECLINE"
4. If "Approved"  → safe to proceed
   If "Declined" → check email.warnings for reason, block or warn user

Utility Scripts

verify_email.py: Send and check email verification codes from the command line.

# Requires: pip install requests
export DIDIT_API_KEY="your_api_key"

python scripts/verify_email.py send user@example.com
python scripts/verify_email.py check user@example.com 123456 --decline-breached --decline-disposable

Can also be imported as a library:

from scripts.verify_email import send_code, check_code

send_result = send_code("user@example.com")
check_result = check_code("user@example.com", "123456", decline_breached=True)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

didit-face-match

No summary provided by upstream source.

Repository SourceNeeds Review
General

didit-database-validation

No summary provided by upstream source.

Repository SourceNeeds Review
General

didit-proof-of-address

No summary provided by upstream source.

Repository SourceNeeds Review
General

didit-phone-verification

No summary provided by upstream source.

Repository SourceNeeds Review