Didit Email Verification
Integrate Didit Email Verification standalone API to verify email addresses via OTP.
- Rating
- 4.3 (249 reviews)
- Downloads
- 786 downloads
- Version
- 1.0.0
Overview
Integrate Didit Email Verification standalone API to verify email addresses via OTP.
Complete Documentation
View Source →
Didit Email Verification API
Overview
Two-step email verification via one-time code:
- Send a verification code to an email address
- Check the code the user provides
- 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
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:
- Register:
POST https://apx.didit.me/auth/v2/programmatic/register/with{"email": "[email protected]", "password": "MyStr0ng!Pass"} - Check email for a 6-character OTP code
- Verify:
POST https://apx.didit.me/auth/v2/programmatic/verify-email/with{"email": "[email protected]", "code": "A3K9F2"}→ response includesapi_key
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
| Header | Value | Required |
|---|---|---|
| x-api-key | Your API key | Yes |
| Content-Type | application/json | Yes |
Body (JSON)
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| string | Yes | — | Valid email | Email address to send code to | |
| options.code_size | integer | No | 6 | Min: 4, Max: 8 | Length of the verification code |
| options.alphanumeric_code | boolean | No | false | — | true = A-Z + 0-9 (case-insensitive) |
| options.locale | string | No | — | Max 5 chars | Locale for email template. e.g. en-US |
| signals.ip | string | No | — | IPv4 or IPv6 | User's IP for fraud detection |
| signals.device_id | string | No | — | Max 255 chars | Unique device identifier |
| signals.user_agent | string | No | — | Max 512 chars | Browser/client user agent |
| vendor_data | string | No | — | — | Your 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": "[email protected]",
"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: "[email protected]",
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
| Status | Meaning | Action |
|---|---|---|
| "Success" | Code sent | Proceed — wait for user to provide code, then call Check |
| "Retry" | Temporary delivery issue | Wait a few seconds and retry Send (max 2 retries) |
| "Undeliverable" | Email cannot receive mail | Inform user the email is invalid or cannot receive messages |
Error Responses
| Code | Meaning | Action |
|---|---|---|
| 400 | Invalid request body or email | Check email format and parameter constraints |
| 401 | Invalid or missing API key | Verify x-api-key header |
| 403 | Insufficient credits/permissions | Check credits in Business Console |
| 429 | Rate limited | Back 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
| Header | Value | Required |
|---|---|---|
| x-api-key | Your API key | Yes |
| Content-Type | application/json | Yes |
Body (JSON)
| Parameter | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
| string | Yes | — | Valid email | Same email used in Step 1 | |
| code | string | Yes | — | 4-8 chars | The code the user received |
| duplicated_email_action | string | No | "NO_ACTION" | "NO_ACTION" / "DECLINE" | Decline if email already verified by another user |
| breached_email_action | string | No | "NO_ACTION" | "NO_ACTION" / "DECLINE" | Decline if email found in data breaches |
| disposable_email_action | string | No | "NO_ACTION" | "NO_ACTION" / "DECLINE" | Decline if email is disposable/temporary |
| undeliverable_email_action | string | No | "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. Theemail.*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": "[email protected]",
"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: "[email protected]",
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": "[email protected]",
"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
| Status | Meaning | Action |
|---|---|---|
| "Approved" | Code correct, no policy violations | Email verified — proceed with your flow |
| "Failed" | Code incorrect | Ask user to re-enter. After 3 failures, resend a new code |
| "Declined" | Code correct but policy violation | Inform user. Check email.warnings for reason |
| "Expired or Not Found" | No pending code | Code expired (>5 min) or Send was never called. Resend |
Error Responses
| Code | Meaning | Action |
|---|---|---|
| 400 | Invalid request body | Check email and code format |
| 401 | Invalid or missing API key | Verify x-api-key header |
| 403 | Insufficient credits/permissions | Check credits in Business Console |
| 404 | Code expired or not found | Resend a new code via Step 1 |
Response Field Reference
email Object
| Field | Type | Description |
|---|---|---|
| status | string | "Approved", "Failed", "Declined" |
| string | The email address verified | |
| is_breached | boolean | Found in known data breaches |
| breaches | array | Breach details: {name, domain, breach_date, data_classes, breach_emails_count} |
| is_disposable | boolean | From a disposable/temporary provider |
| is_undeliverable | boolean | Cannot receive email |
| verification_attempts | integer | Number of check attempts (max 3) |
| verified_at | string | ISO 8601 timestamp when verified (null if not) |
| warnings | array | Risk warnings: {risk, log_type, short_description, long_description} |
| lifecycle | array | Event log: {type, timestamp, fee} |
Warning Tags
| Tag | Description | Auto-Decline |
|---|---|---|
| EMAIL_CODE_ATTEMPTS_EXCEEDED | Max code entry attempts exceeded | Yes |
| EMAIL_IN_BLOCKLIST | Email is in blocklist | Yes |
| UNDELIVERABLE_EMAIL_DETECTED | Email cannot be delivered | Yes |
| BREACHED_EMAIL_DETECTED | Found in known data breaches | Configurable |
| DISPOSABLE_EMAIL_DETECTED | Disposable/temporary provider | Configurable |
| DUPLICATED_EMAIL | Already verified by another user | Configurable |
error (critical), warning (requires attention), information (informational).Common Workflows
Basic Email Verification
1. POST /v3/email/send/ → {"email": "[email protected]"}
2. Wait for user to provide the code
3. POST /v3/email/check/ → {"email": "[email protected]", "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 [email protected]
python scripts/verify_email.py check [email protected] 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("[email protected]")
check_result = check_code("[email protected]", "123456", decline_breached=True)
Installation
openclaw install didit-email-verification
💻Code Examples
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": "[email protected]", "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": "[email protected]", "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.
### RequestPOST https://verification.didit.me/v3/email/send/
### Headers
| Header | Value | Required |
|---|---|---|
| `x-api-key` | Your API key | **Yes** |
| `Content-Type` | `application/json` | **Yes** |
### Body (JSON)
| Parameter | Type | Required | Default | Constraints | Description |
|---|---|---|---|---|---|
| `email` | string | **Yes** | — | Valid email | Email address to send code to |
| `options.code_size` | integer | No | `6` | Min: 4, Max: 8 | Length of the verification code |
| `options.alphanumeric_code` | boolean | No | `false` | — | `true` = A-Z + 0-9 (case-insensitive) |
| `options.locale` | string | No | — | Max 5 chars | Locale for email template. e.g. `en-US` |
| `signals.ip` | string | No | — | IPv4 or IPv6 | User's IP for fraud detection |
| `signals.device_id` | string | No | — | Max 255 chars | Unique device identifier |
| `signals.user_agent` | string | No | — | Max 512 chars | Browser/client user agent |
| `vendor_data` | string | No | — | — | Your identifier for session tracking |
### Example}
### Status Values & Handling
| Status | Meaning | Action |
|---|---|---|
| `"Success"` | Code sent | Proceed — wait for user to provide code, then call Check |
| `"Retry"` | Temporary delivery issue | Wait a few seconds and retry Send (max 2 retries) |
| `"Undeliverable"` | Email cannot receive mail | Inform user the email is invalid or cannot receive messages |
### Error Responses
| Code | Meaning | Action |
|---|---|---|
| `400` | Invalid request body or email | Check email format and parameter constraints |
| `401` | Invalid or missing API key | Verify `x-api-key` header |
| `403` | Insufficient credits/permissions | Check credits in Business Console |
| `429` | Rate limited | Back 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.
### RequestPOST https://verification.didit.me/v3/email/check/
### Headers
| Header | Value | Required |
|---|---|---|
| `x-api-key` | Your API key | **Yes** |
| `Content-Type` | `application/json` | **Yes** |
### Body (JSON)
| Parameter | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
| `email` | string | **Yes** | — | Valid email | Same email used in Step 1 |
| `code` | string | **Yes** | — | 4-8 chars | The code the user received |
| `duplicated_email_action` | string | No | `"NO_ACTION"` | `"NO_ACTION"` / `"DECLINE"` | Decline if email already verified by another user |
| `breached_email_action` | string | No | `"NO_ACTION"` | `"NO_ACTION"` / `"DECLINE"` | Decline if email found in data breaches |
| `disposable_email_action` | string | No | `"NO_ACTION"` | `"NO_ACTION"` / `"DECLINE"` | Decline if email is disposable/temporary |
| `undeliverable_email_action` | string | No | `"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}
### Status Values & Handling
| Status | Meaning | Action |
|---|---|---|
| `"Approved"` | Code correct, no policy violations | Email verified — proceed with your flow |
| `"Failed"` | Code incorrect | Ask user to re-enter. After 3 failures, resend a new code |
| `"Declined"` | Code correct but policy violation | Inform user. Check `email.warnings` for reason |
| `"Expired or Not Found"` | No pending code | Code expired (>5 min) or Send was never called. Resend |
### Error Responses
| Code | Meaning | Action |
|---|---|---|
| `400` | Invalid request body | Check email and code format |
| `401` | Invalid or missing API key | Verify `x-api-key` header |
| `403` | Insufficient credits/permissions | Check credits in Business Console |
| `404` | Code expired or not found | Resend a new code via Step 1 |
---
## Response Field Reference
### `email` Object
| Field | Type | Description |
|---|---|---|
| `status` | string | `"Approved"`, `"Failed"`, `"Declined"` |
| `email` | string | The email address verified |
| `is_breached` | boolean | Found in known data breaches |
| `breaches` | array | Breach details: `{name, domain, breach_date, data_classes, breach_emails_count}` |
| `is_disposable` | boolean | From a disposable/temporary provider |
| `is_undeliverable` | boolean | Cannot receive email |
| `verification_attempts` | integer | Number of check attempts (max 3) |
| `verified_at` | string | ISO 8601 timestamp when verified (`null` if not) |
| `warnings` | array | Risk warnings: `{risk, log_type, short_description, long_description}` |
| `lifecycle` | array | Event log: `{type, timestamp, fee}` |
---
## Warning Tags
| Tag | Description | Auto-Decline |
|---|---|---|
| `EMAIL_CODE_ATTEMPTS_EXCEEDED` | Max code entry attempts exceeded | Yes |
| `EMAIL_IN_BLOCKLIST` | Email is in blocklist | Yes |
| `UNDELIVERABLE_EMAIL_DETECTED` | Email cannot be delivered | Yes |
| `BREACHED_EMAIL_DETECTED` | Found in known data breaches | Configurable |
| `DISPOSABLE_EMAIL_DETECTED` | Disposable/temporary provider | Configurable |
| `DUPLICATED_EMAIL` | Already verified by another user | Configurable |
Warning severity levels: `error` (critical), `warning` (requires attention), `information` (informational).
---
## Common Workflows
### Basic Email VerificationIf "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.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": "[email protected]",
"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: "[email protected]",
options: { code_size: 6 },
signals: { ip: "203.0.113.42" },
}),
});{
"request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
"status": "Success",
"reason": null
}response = requests.post(
"https://verification.didit.me/v3/email/check/",
headers={"x-api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
json={
"email": "[email protected]",
"code": "123456",
"breached_email_action": "DECLINE",
"disposable_email_action": "DECLINE",
},
)Tags
Quick Info
Ready to Install?
Get started with this skill in seconds
Related Skills
4claw
4claw — a moderated imageboard for AI agents.
Aap Passport
Agent Attestation Protocol - The Reverse Turing Test.
Acestep Lyrics Transcription
Transcribe audio to timestamped lyrics using OpenAI Whisper or ElevenLabs Scribe API.
Adaptive Suite
A continuously adaptive skill suite that empowers Clawdbot.