The dangerous version of a lead verification API is a single boolean. It hides which evidence was checked, which provider failed, which Business policy ran, and whether the caller can safely retry. A useful contract preserves those boundaries before a Lead reaches any Destination.

The five layers of a safe response contract

Five layers of a safe Lead Validation API response contract
Layer Required fields Question answered Must stay separate from
HTTP Status, content type, request or trace ID Could the API accept and process this request? The Lead's Validation Outcome
Validation Run Run ID, outcome, reasons, policy version, started and completed times Is this Lead safe to route under the stated policy? Any one field or provider result
Validation Check Type, status, provider, confidence, reasons, checked time What evidence did this field or signal produce? The overall decision
Failure Scope, stable code, retryable flag, safe detail Did input, policy, provider, or infrastructure fail? Negative contact evidence
Next action Deliver, hold for review, do not deliver, or retry according to policy What may the routing system do now? Proof that a Delivery succeeded

This is an architectural recommendation, not a universal wire format. If the API needs a standard HTTP error body, RFC 9457 defines application/problem+json and the type, status, title, detail, and instance members. Keep that transport error beside, not inside, a successful domain response.

A synthetic lead validation response

The example below contains no personal data. It shows a locally valid phone check, an unavailable email provider, and a review outcome. The timeout remains visible as missing evidence instead of being converted into an invalid email.

{
  "validation_run_id": "vr_demo_01",
  "outcome": "review",
  "reason_codes": ["EMAIL_EVIDENCE_UNAVAILABLE"],
  "policy_version": "business-default-v3",
  "next_action": "hold_for_review",
  "started_at": "2026-08-24T08:30:00Z",
  "completed_at": "2026-08-24T08:30:02Z",
  "checks": [
    {
      "type": "phone",
      "status": "valid",
      "normalized_value": null,
      "value_redacted": true,
      "provider": "local",
      "confidence": "high",
      "checked_at": "2026-08-24T08:30:00Z",
      "reason_codes": ["PHONE_RANGE_VALID"]
    },
    {
      "type": "email",
      "status": "unknown",
      "normalized_value": null,
      "value_redacted": true,
      "provider": "example-provider",
      "confidence": null,
      "checked_at": "2026-08-24T08:30:02Z",
      "reason_codes": ["PROVIDER_TIMEOUT"],
      "error": {
        "code": "EMAIL_PROVIDER_TIMEOUT",
        "retryable": true
      }
    }
  ]
}

Real responses may return authorized normalized values, but every consumer does not need them. Prefer field presence or a redacted representation when routing only needs status and reasons.

1. Preserve independent Validation Checks

Phone, email, address, name, duplicate, and source evidence have different meanings. A common check envelope makes them comparable without pretending they are the same signal. Use the stable Lucidity statuses valid, invalid, risky, unknown, and missing, then attach check-specific reason codes.

Provider taxonomies should be preserved at the boundary and mapped deliberately. For example, Twilio Lookup v2 returns a valid field and optional validation errors for invalid number ranges. The current ZeroBounce v2 email response uses statuses including valid, invalid, catch-all, and unknown, plus more specific sub-statuses. Those vendor values are evidence, not a universal routing policy.

2. Return one explicit Validation Outcome

Lead Validation outcomes, meanings, and allowed next actions
Outcome Meaning Allowed next action What it does not prove
qualified Forwardable under the recorded Business policy Create Delivery attempts for eligible Destinations That any Delivery succeeded
review Evidence is ambiguous, conflicting, duplicate, or incomplete Hold for an operator or an explicit review policy That the Lead is bad
blocked High-confidence evidence says the Lead is not forwardable Do not deliver automatically That every submitted field was invalid
error The Validation Run could not complete Apply the recorded Business fallback or retry policy That the Lead failed validation

The decisive boundary is between blocked and error. A blocked Lead has negative evidence. An error describes a failed decision process. Lucidity's Lead Validation documentation explains the same contactability-first principle: provider unavailability records evidence but should not automatically erase a locally valid contact path.

3. Make partial provider failure recoverable

  1. Run deterministic checks first. Normalize and validate fields that do not need an external provider.
  2. Give providers a bounded budget. Record their start time, duration, package, and terminal state.
  3. Map absence to unknown. A timeout, unavailable package, or no-data response is not an invalid contact value.
  4. Combine the evidence under one policy version. The aggregator, not an individual provider, produces the overall outcome.
  5. Expose a safe next action. The caller should not have to reverse engineer whether to deliver, hold, stop, or retry.

This matters because provider APIs expose uncertainty differently. ZeroBounce, for example, documents unknown sub-statuses for greylisting, temporary mail-server errors, non-response, and timeouts. Collapsing all of them to invalid would convert temporary infrastructure evidence into a permanent routing decision.

4. Separate request errors from Lead outcomes

Malformed JSON, missing authorization, an unsupported field, a provider timeout, and a blocked Lead belong to different layers. Use HTTP semantics for request and service failure. Return a normal Validation Run representation when the API completed the domain decision, even if that outcome is blocked or review.

A client must never interpret every non-successful provider call as blocked, or every blocked Lead as an HTTP server error. Transport tells the caller whether the operation worked. The Validation Outcome tells routing what may happen to the Lead.

RFC 9457 also warns that problem details are not a debugging tool. Use a stable public problem type and a support-safe instance identifier, but keep stack traces, provider credentials, internal hosts, and raw upstream bodies out of the response.

5. Design timeouts and retries around idempotency

Accept a caller-supplied idempotency key or request identifier when starting a Validation Run. Repeating the same request should return or resume the same logical run, not create duplicate Leads or duplicate downstream work. Record retry state at the failed check so a later attempt does not discard already completed evidence.

Mark errors retryable only when the failure is plausibly transient. A timeout or rate limit may qualify; invalid input and unsupported policy do not. Use bounded attempts, backoff, and a total decision deadline chosen for the workflow. There is no universal retry schedule, so publish the actual policy beside the API contract and test its interaction with routing.

6. Keep the reason taxonomy small and stable

Example Lead Validation reason-code families and safe uses
Reason family Example Use Avoid
Field evidence PHONE_RANGE_INVALID Explain one check result Embedding the submitted value in the code
Cross-check evidence DUPLICATE_RECENT Support review or strict suppression policy Assuming every repeat inquiry is unwanted
Policy requirement REQUIRED_CONTACT_MISSING Explain why the Business policy did not qualify Hiding the policy version
Provider absence PROVIDER_TIMEOUT Drive retry and observability Mapping absence to field invalidity

A reason code should exist because it drives routing, review, reporting, retry, or calibration. Keep human-readable explanations separate so wording can improve without breaking clients.

7. Minimize data in requests, responses, and logs

Send each provider only the fields required for its documented check. Do not forward an entire raw Lead payload to a phone or email service. Return normalized values only to authorized consumers, set retention rules for raw provider evidence, and use opaque identifiers in support tooling.

The OWASP Logging Cheat Sheet recommends removing, masking, sanitizing, hashing, or encrypting access tokens, passwords, sensitive personal data, and other secrets instead of recording them directly. For a validation service, useful logs usually contain the run ID, Business ID, check type, provider, duration, status, reason code, retry count, and policy version. They do not need a full phone number, email address, API key, or raw response body.

8. Measure the decision, not just API uptime

Service health is necessary, but it does not show whether the policy is holding too many reachable people or passing weak evidence. Report each metric with a denominator and a stated time window:

  • Validation Outcomes by Business and policy version
  • Per-check valid, invalid, risky, unknown, and missing rates
  • Provider error and no-data rates by check type
  • Median, p95, and p99 Validation Run duration
  • Review overrides and their original reason codes
  • Delivery attempts and successes after qualification

Keep Lucidity Lead, Validation, and Delivery records as first-party facts. GA4 can add traffic context, but it is not the source of truth for whether a Lead was contactable, held, blocked, routed, or successfully delivered.

Lead Validation API test matrix

Minimum Lead Validation API cases and assertions
Case Expected check evidence Decision assertion
Valid phone, invalid email Two preserved check results Apply the configured contact requirement, not a universal block
Provider timeout Unknown check with provider error and retryability Never rewrite the timeout as invalid contact evidence
Recent duplicate Duplicate reason with the configured Business window Review by default unless strict suppression is explicit
Malformed request No Validation Run created Return a safe HTTP problem, not a blocked outcome
Repeated idempotency key Same logical run and completed evidence No duplicate Lead or Delivery work
Conflicting strong evidence Every original check and reason retained Hold for review under the stated policy

Start with the phone validation API guide for field-level evidence, use the Lead qualification software guide for category choices, and keep successful routing distinct from Delivery proof.

Primary sources checked August 24, 2026

Frequently asked question

What contract should a validation API return so routing decisions are explainable and recoverable?

Return an overall Validation Outcome plus independent field-level checks. Each check should preserve its status, normalized-value availability, provider, confidence, reason codes, and timestamp. Keep provider or transport errors separate from negative contact evidence, expose a safe next action, and include stable identifiers and policy versions so the decision can be audited or retried without duplicating work.

Gate Delivery with evidence you can explain

Bring one Business policy and the phone, email, duplicate, or source checks it needs. See how Lucidity records each Validation Check, holds ambiguous evidence for review, and routes from one explicit Validation Outcome.

Request a Lead Validation walkthrough