---
title: "Verify single email"
method: POST
path: "/v1/verify/single"
tags: ["Verification"]
---

# Verify single email

`POST /v1/verify/single`

## Request

- Base URL: `https://api.billionverify.com`
- URL: `https://api.billionverify.com/v1/verify/single`
- Auth: API key in header `BV-API-KEY`

Verify a single email address in real-time. Returns detailed verification results including
deliverability status, domain information, and risk assessment.

## Request body

- SingleVerifyRequest
  - `email` string, email, required: Email address to verify
  - `check_smtp` boolean: Optional SMTP override: when omitted, the server default applies (production: enabled). true explicitly enables SMTP; false explicitly disables SMTP for this request.
  - `force_refresh` boolean: Bypass cached results and force a fresh live verification. When true, all cache layers are skipped and a credit is always consumed.
  - `include_domain_reputation` boolean: When true and a cached result is returned, also synchronously fetch the domain MX IP reputation (blacklist status). Adds a small latency cost but enriches `domain_reputation` in the response.

## Response `200`

Verification successful

- SingleVerifyApiResponse
  - `success` boolean
  - `code` string
  - `message` string
  - `data` EmailVerificationResult
    - `email` string, email: The verified email address
    - `status` 'valid' | 'invalid' | 'unknown' | 'risky' | 'disposable' | 'catchall' | 'role': Verification status. `unknown` is the only status meaning "we could not reach a conclusion" (retry may help; not billed). `risky` means the address is most likely deliverable but its domain carries a confirmed abuse history — see `risk_reasons`; it is a deterministic conclusion, is billed, and retrying will not change it.
    - `score` number, float: Quality score (0-1)
    - `is_deliverable` boolean: Whether the verification channel confirmed that the target address is deliverable. The evidence may come from SMTP or a supported provider API, and can coexist with is_catchall and is_role.
    - `is_disposable` boolean: Whether it's a disposable/temporary email
    - `is_catchall` boolean: Whether the domain accepts all emails
    - `is_role` boolean: Whether it's a role-based email (info@, support@, etc.)
    - `is_free` boolean: Whether it's from a free email provider
    - `domain` string: Email domain
    - `domain_age` integer, nullable: Domain age in years (omitempty in Go = pointer; absent when unknown).
    - `mx_records` string[], nullable: MX records for the domain (omitempty array).
    - `mx_ip` string, nullable: Primary MX IP address when known (pointer in Go; absent if MX unresolved).
    - `mx_asn` integer: Primary MX autonomous system number when known
    - `mx_as_org` string, nullable: Primary MX autonomous system organization when known (pointer in Go).
    - `domain_reputation` DomainReputation: MX IP reputation (blacklist) info attached to a verification result. Display-only: never affects `status`, `score`, `reason`, or billing. `drop_*` fields come from the Spamhaus DROP dataset (netblocks controlled by criminal operations / bulletproof hosters). DROP is used under the Spamhaus Project's free licence, which requires attribution — `drop_attribution` carries the copyright and terms text and must be surfaced wherever `drop_listed` is shown.
      - `mx_ip` string, nullable: IP address of the MX server (omitempty in Go).
      - `is_listed` boolean: Whether the IP is on any blacklist
      - `blacklists` string[]: List of blacklists where the IP appears (sorted)
      - `advisory` string[]: Zones that answered with a graded, non-listing code (currently `dnsbl.spfbl.net`: any code other than `127.0.0.2`, e.g. grey-list `.3` / low-reputation `.4`). Informational only: never sets `is_listed`. Omitted when empty.
      - `checked` boolean: Whether reputation check was performed
      - `drop_listed` boolean: MX IP falls inside a Spamhaus DROP netblock. Omitted when false.
      - `drop_cidr` string: The matching DROP netblock. Present only when `drop_listed` is true.
      - `drop_sblid` string: Spamhaus SBL reference for the listing; look it up on spamhaus.org for the reason.
      - `drop_attribution` string: Required Spamhaus Project attribution for the DROP data (copyright + terms URL).
    - `check_smtp` boolean: Whether the result includes SMTP verification data
    - `smtp_result` 'not_checked' | 'deliverable' | 'undeliverable' | 'inconclusive': SMTP channel outcome, independent of the main status. For example, disposable, role, and catchall can coexist with deliverable.
    - `catch_all_evidence` 'direct_no' | 'cached_no' | 'direct_yes' | 'cached_yes' | 'blocked' | 'tempfail' | 'unknown': How the domain-level catch-all probe behaved for this result. direct_no / cached_no mean a random recipient was rejected (the domain is not catch-all); direct_yes / cached_yes mean it was accepted (the domain is catch-all); blocked / tempfail / unknown mean the probe was inconclusive. Absent when no SMTP probe ran (provider API path, syntax / DNS short-circuit, legacy history). A valid result scores 1.00 only with direct_no or cached_no.
    - `reason` string: Detailed reason for the verification result. Rule-based reasons include smtp_deliverable, mailbox_not_found, no_mx_records, invalid_syntax, disposable_domain, role_account, catch_all_domain, catch_all_inferred, m365_internal_relay, gateway_accept_all, forwarding_alias, smtp_unverifiable, smtp_greylisted, mimecast_greylist, proofpoint_ad_lookup, smtp_timeout, dns_timeout, smtp_rate_limited, smtp_blocked, smtp_eof_blocked, smtp_connection_failed, smtp_egress_unavailable, smtp_egress_unselectable, yahoo_api_rate_limited, m365_ip_rep_block, google_rate_limit, google_dmarc_misalignment, mailbox_full, policy_temp_fail, smtp_550_unclassified, and null_mx.
    - `suggestion` string: Deprecated. Use `domain_suggestion`.
    - `domain_suggestion` string: Suggested correction if typo detected
    - `alias_of` string, email: The canonical email address, present only when the submitted address differs from it. Detects Gmail dot-insensitive / plus-addressing aliases (`alice+news@gmail.com` -> `alice@gmail.com`) and Microsoft consumer plus-addressing (`outlook.com`, `hotmail.com`, `live.com`, `msn.com`). Display hint only: does not affect status, score, or billing. See docs/verification/alias/alias-detection.md.
    - `risk_reasons` string[]: External risk signals that downgraded an otherwise deliverable address to `risky`. Historically sourced from the Spamhaus Domain Blocklist (DBL) lookup on the recipient domain; that lookup was retired on 2026-09-11, so new results no longer carry these values. Absent or empty when no external risk signal matched. A `risky` result means the mailbox most likely *does* accept mail, but the recipient domain has a confirmed abuse history — sending to it can damage your sending reputation. Treat it like `disposable`: remove it from the list. Domains listed by Spamhaus as *abused legitimate sites* (compromised but otherwise normal websites) are deliberately excluded and never produce a `risky` result.
    - `smtp_response` string, nullable: Redacted raw SMTP response detail. Only returned for accounts or API keys in the verbose SMTP response allowlist (pointer in Go = absent for most clients).
    - `response_time` integer: Response time in milliseconds
    - `credits_used` integer: Number of credits consumed
    - `verification_mode` 'smtp' | 'yahoo_api' | 'cache_hit_global' | 'cache_hit_user' | 'cache_hit_db_history' | 'cache_hit_transient' | 'skip_anti_verification' | 'skip_smtp_unknown' | 'syntax_only' | 'unknown_path': Q4 (2026-05-08): Which verification path produced this result. Helps clients interpret retryability and explain billing.
    - `retryable` boolean: Q4 (2026-05-08): Whether re-running with `force_refresh=true` could yield a different result. true for transient unknowns (rate_limited / timeouts / yahoo_api unavailable). false for deterministic outcomes and for anti-verification / smtp_blocked / dmarc misalignment. Only `unknown` results can ever be retryable. `risky` is a deterministic conclusion and is always false (changed 2026-08-04).
    - `smtputf8` boolean: P1-2 (2026-05-13): True when the email's local-part contains any non-ASCII character (RFC 6531 SMTPUTF8 required). Clients planning to send mail to this address must use an outbound MTA that supports the SMTPUTF8 extension; MTAs lacking SMTPUTF8 will reject non-ASCII local-parts. Borrowed from JoshData/python-email-validator `ValidatedEmail.smtputf8`.
    - `retry_after_seconds` integer, nullable: SMTP retry hint parsed from a transient remote SMTP response body (for example greylisting "try again in 60 seconds"). Omitted when the remote server did not provide a usable delay.
  - `error` ErrorInfo
    - `code` string: Detailed error code
    - `message` string: Detailed error message
    - `description` string, nullable: Additional human-readable context (omitempty in Go)
    - `details` unknown

## Other responses

- `400`: Bad request - invalid parameters
- `401`: Unauthorized - invalid or missing API key
- `402`: Payment required - insufficient credits
- `429`: Rate limit exceeded

---

[API](https://skmtc.dev/billionverify/apis/billionverify-api.md) · [All operations](https://skmtc.dev/billionverify/apis/billionverify-api/llms.txt) · [OpenAPI document](https://skmtc.dev/billionverify/apis/billionverify-api/revisions/00762347dc27?raw)
