How to Define Success and Error Responses in OpenAPI for Email Verification
Learn how to structure clear success and error responses in OpenAPI for email verification APIs.
Why Clear OpenAPI Responses Matter for Email Verification Services
You've integrated an email verification API, but your system keeps retrying emails that are clearly invalid. Or worse—your dashboard shows a "success" status, but those emails never reach inboxes. Why does this happen? Because ambiguous API responses turn integration from simple verification into a debugging marathon.
Email verification isn’t just yes or no. It’s a stateful process: an address can be valid, temporarily unreachable, permanently undeliverable, a catch-all, or risky due to domain behavior. Each outcome needs a precise response—no guessing. How you define success and error responses in OpenAPI shapes whether your client app knows when to retry, alert, or remove an address.
Well-structured OpenAPI specs with clearly mapped status codes and detailed response bodies turn unreliable email validation into an automated, trustworthy process. This matters because every ambiguous response costs time, increases bounces, and weakens sender reputation.
Key takeaways
- Defining explicit success and error statuses in OpenAPI prevents client apps from misinterpreting temporary failures as final rejections.
- Responses must distinguish between permanent failures (e.g., invalid syntax), temporary issues (e.g., greylist), and edge cases like catch-all or risky domains.
- Clear OpenAPI responses enable automated hygiene workflows—removal of risky domains, retries for transient errors, and alerts for suspicious patterns—without manual oversight.
What Does a Valid OpenAPI Response Look Like for Email Verification?
A valid OpenAPI response for email verification returns an HTTP 200 status, a consistent JSON structure, and a clear verdict—valid, invalid, catch-all, or risky—on the input email. The response body must include at minimum the original email address, the verification status, and a timestamp. Optional fields may add confidence scores, reason codes, or delivery risk indicators. This consistency is critical for reliable integration and error handling.
Structure and Status Codes
You’ll immediately know a response is valid if it returns HTTP 200 with a properly formatted JSON body. Any other status—like 4xx or 5xx—indicates a problem on the client or server side, not a result from the verification process. The 200 response confirms the request was understood and processed, which is the baseline for defining success.
According to the IETF’s HTTP specification (RFC 7231), success responses should be clearly distinguished by status codes like 200, 201, or 204. In email verification, 200 is the only valid success code; others indicate a failure in the call, not in the email’s validity itself.
Required and Optional Fields in the Response Body
The core payload must include the input email, the verification outcome (valid, invalid, catch-all, risky), and a timestamp. These three fields form the minimal contract between your app and the verification service. Without them, your system cannot act on the result.
Adding optional fields improves the value of the response. A confidence score—typically a float between 0 and 1—lets your app weigh results. Reason codes (like 'syntax', 'domain_not_found', 'disposable') help debug edge cases. Delivery risk indicators—such as a flag for known spam traps or role-based emails—help you avoid future deliverability issues.
- input_email: The original email address submitted.
- status: One of: valid, invalid, catch-all, risky.
- timestamp: When the verification was processed, in ISO 8601 format.
- confidence: Optional; a numerical score reflecting certainty.
- reason_codes: Optional; array of diagnostic tags.
- delivery_risk: Optional; flag or score for deliverability concerns.
| Item | Details |
|---|---|
| input_email | The original email address submitted. |
| status | One of: valid, invalid, catch-all, risky. |
| timestamp | When the verification was processed, in ISO 8601 format. |
| confidence | Optional; a numerical score reflecting certainty. |
| reason_codes | Optional; array of diagnostic tags. |
| delivery_risk | Optional; flag or score for deliverability concerns. |
When you’re building integrations with tools like Emaillistchecker.io’s verification API, having this structure from the start means fewer downstream bugs and faster scaling. It also makes testing and logging straightforward.
If you’re validating a list at scale, consistent responses allow you to parse results automatically. You can filter out invalid emails, flag risky ones, and focus only on high-confidence addresses. This directly improves deliverability and sender reputation over time.
How to Define Success Responses Using OpenAPI Schema
You define a successful email verification response in OpenAPI by using the 200 status code and specifying a clear JSON schema under components.schemas.VerificationResponse. Include required fields like email, status, and timestamp for consistency. Add optional fields like verdict, confidence, and reason for debugging, without overloading the core response. This keeps your API predictable and easy to consume.
Set up the 200 response with a well-structured schema
- Use
200as the primary success response code. It’s the industry-standard indicator that the request was processed and the data is valid. Using200correctly ensures tools like Postman, Swagger UI, and monitoring systems interpret the response as expected. - Define your response shape under
components.schemas.VerificationResponse. This makes the schema reusable across multiple endpoints and avoids duplication. It aligns with OpenAPI best practices and improves developer experience. - Include the required fields:
email(string),status(string, e.g., "valid"), andtimestamp(ISO 8601 format). These are non-negotiable for reliable downstream processing. Missing any can break automated workflows. - Optional but valuable fields:
verdict(e.g., "valid", "risky", "catch-all") gives immediate insight into the result.confidence(0–100) quantifies the system’s certainty.reason(string) explains why—common for debugging.details(object) holds vendor-specific indicators like SMTP status codes or MX lookup results. - Keep the schema minimal but extendable. Avoid nesting complex objects unless necessary. Use plain JSON—no custom types or unstructured data. This ensures compatibility with all clients, including low-code tools and mobile apps.
Why this matters for real-world email verification
Having a clear, validated response format means your integration doesn’t fail on malformed or incomplete data. A well-defined 200 response reduces false positives and makes error handling predictable. For example, if a client receives a status: "invalid" with a reason: "no MX record", they know to flag that domain early.
For teams building email verification pipelines, this clarity saves hours in debugging and improves deliverability outcomes. You can test your schema against real data using tools like IANA’s DNS records or MxToolbox to validate MX and SPF configurations.
If you're building a verification service, consider starting with our API integration to see how a production-ready schema performs at scale—no credit card needed.
How to Define Error Responses for Common Email Verification Failures
You should use HTTP status codes like 400 for malformed input, 403 for authentication issues, and 429 for rate limiting, and define error responses in components.schemas.ErrorResponse with code, message, and details fields. Never use 500 for expected failures like invalid or blocked domains—reserve it for actual server-side errors. This keeps your API predictable and helps clients respond correctly.
Match Status Codes to Real-World Failure Types
Let’s start with the basics: every error should map to the right HTTP status code. A 400 response means the client sent malformed data—like an invalid email format or missing required fields. If the request lacks proper authentication, use 403. This is standard practice across APIs, and tools like RFC 7231 define these codes precisely. When a client exceeds your API’s rate limit, return 429. This gives the client a clear signal it needs to slow down.
Don’t return 500 for expected failures. A 500 error means something broke on the server—like a database crash or unhandled exception. If a domain is blocked or an email is syntactically invalid, that’s not a server issue. Returning 500 here misleads clients, who might assume the system is unstable when it’s not. It’s better to respond with a 400 or even a 200 with a specific error code in the response body.
Structure Errors for Clarity and Actionability
Define your error responses in a shared schema—like components.schemas.ErrorResponse. Include at minimum three fields: code, message, and details. The code should be a consistent, machine-readable identifier (e.g., INVALID_EMAIL, DOMAIN_BLOCKED). The message should be a brief, human-readable explanation. The details field can contain more specific information—like the exact domain or a reference to internal logic.
For example, if an email fails because it’s from a disposable domain, your response could include code: DISPOSABLE_DOMAIN, message: "Email uses a temporary domain", and details: {"domain": "tempmail.org"}. This makes debugging easy. You can also include context from services like Spamhaus or MxToolbox to validate blocking logic.
When building integrations, clear error responses help users know when they need to fix input or retry. Use the Email Verification API to test how structured errors behave at scale, and ensure your documentation reflects the actual response shapes you return.
Common Verdicts and Their Mapping to HTTP Responses
You should map email verification verdicts to specific HTTP status codes and response bodies to ensure reliable integration. A valid email returns 200 OK with status: "valid". Invalid emails use 400 Bad Request with a reason like "syntax" or "domain_not_found". Catch-all addresses return 200 OK with status: "catch-all" and confidence ≥0.7. Risky emails return 200 OK with status: "risky" and a reason like "high_bounce_rate" or "role_account". This approach aligns with industry-standard API design patterns for deliverability tools.
Standardized Response Mapping
Each verification result must be clearly communicated in the API response. This prevents clients from misinterpreting behavior and supports robust error handling. The table below shows how common verdicts map to HTTP codes and JSON content. This structure is used across leading email validation services, including those used by enterprise senders who rely on accurate filtering.
| Verdict | HTTP Status | Response Body | When to Use |
|---|---|---|---|
| Valid | 200 OK | {"status": "valid"} |
When the email is syntactically correct, the domain resolves, and the mailbox accepts messages. |
| Invalid | 400 Bad Request | {"status": "invalid", "reason": "syntax"} or "domain_not_found" |
For malformed addresses or domains that don’t exist in DNS. |
| Catch-all | 200 OK | {"status": "catch-all", "confidence": 0.75} |
When the server accepts any email at the domain, but you can’t verify individual addresses. Use carefully — higher confidence values (≥0.7) are more reliable. |
| Risky | 200 OK | {"status": "risky", "reason": "high_bounce_rate"} or "role_account" |
For addresses like admin@, support@, or known high-bounce domains. Mark these for manual review or exclusion. |
Why This Matters for Deliverability
Returning consistent, predictable HTTP and JSON responses helps clients filter out bad data before sending. Misreporting catch-all or risky emails increases bounce rates and harms sender reputation — a well-documented factor in inbox placement [RFC 8098]. Tools like EmailListChecker.io use these standards to deliver 98.9% accuracy across bulk validations and real-time APIs. You can test your own list and see the verdicts in action at bulk verification.
How to Handle Rate Limits and Temporary Failures in OpenAPI
Return HTTP 429 Too Many Requests with a Retry-After header in seconds, and include a rate_limit object in the response body with limit, remaining, and reset timestamps. Never retry silently—clients must handle pauses and resumptions explicitly to avoid overwhelming systems. This is standard practice for APIs serving high-volume services like email verification.
Why HTTP 429 and Retry-After Are Essential
You’re not just managing traffic—you're protecting system stability. When an email verification API hits its processing ceiling, HTTP 429 signals the client to pause. The Retry-After header tells them exactly how long to wait, in seconds. This is defined in RFC 6585, which formalizes HTTP status codes for rate-limiting use cases—something every robust API should follow.
Without this, clients might retry immediately, flooding the system and increasing the chance of temporary blocks or degraded performance. For large-scale email list verification, this kind of control prevents collateral damage during peak usage. It’s not just about stopping abuse—it's about preserving reliability for everyone.
Include a Rate Limit Response Object
Don’t rely solely on headers. Include a rate_limit object in the response body with three fields: limit (requests per window), remaining (how many you can still make), and reset (when the window resets, as a Unix timestamp). This gives clients a clear, up-to-date view of their usage state.
For example, if reset is 1715234400, you know the limit refreshes at around 2024-05-08 08:00:00 UTC. This data allows clients to plan retries intelligently—not just react. It’s also critical for long-running processes like list validation across multiple API calls.
Never make clients guess. A missing or incomplete rate limit object forces them to reverse-engineer behavior, increasing the risk of errors. When you provide full visibility, they can implement grace periods and retry logic that respects your system’s limits.
Let’s say you're integrating email verification into a CRM. With proper 429 handling and detailed rate limit data, your app can pause, log progress, and resume later without losing data. This is how you build trustworthy, scalable interactions—whether you're validating 100 emails or 100,000.
For real-world implementation with accurate results, consider tools like EmailListChecker’s real-time verification API, which handles these edge cases consistently and delivers 98.9% accuracy on bulk checks.
Why Status 200 Should Include ‘Risky’ or ‘Catch-All’ Verdicts
Returning 200 OK for “risky” or “catch-all” email addresses is the right approach because verification isn’t binary—some emails exist but shouldn’t be sent to. Using 200 status allows your app to treat these as valid, while still flagging them for review or exclusion based on your deliverability strategy. This clarity prevents false positives and supports smarter list management.
Catch-All Domains Aren’t Always Useful
Many domains are set up to accept any incoming email, even for invalid addresses. These are catch-all domains, and while they technically accept mail, you can’t verify a specific user. Returning “catch-all” as a response under HTTP 200 signals this limitation without rejecting the address outright. This way, you don’t lose potentially valid users simply because the domain is permissive.
Risky Addresses Are Valid — But Not Safe to Send To
Consider [email protected] or [email protected]. These often resolve as valid, but they're rarely opened. They’re not fake—they’re just poor deliverability candidates. In OpenAPI, returning “risky” as a status within a 200 response lets your application decide whether to keep such emails for record-keeping, or filter them out before sending. This distinction is essential when balancing list size against actual engagement.
Industry resources like RFC 5321 define SMTP-level validation behavior, but they don’t resolve the business question: “Is this email worth sending to?” The answer depends on your goals. A 200 response with clear, structured verdicts (like “valid,” “risky,” “catch-all”) gives you that control. Tools like bulk email verification use this same model to return rich, actionable results without relying on error codes to signal non-fatal issues.
Defining Input Validation in OpenAPI for Email Verification
You should enforce email format validation using format: email and a strict pattern in your OpenAPI schema, then return a clear 400 error with invalid_email_syntax when input fails. This stops malformed data early, improves audit logs, and prevents downstream failures in verification workflows.
- Define email format using
format: emailin your request schema. This leverages standard validation built into OpenAPI tools and helps catch basic issues like missing @ or domain parts. It’s a widely supported convention across API clients and documentation tools. - Add a regex
patternto catch edge cases. Use^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$to enforce a valid local and domain part structure. This prevents things like[email protected]or[email protected]from being accepted—even ifformat: emailpasses. - Return 400 with a specific error code. When validation fails, return HTTP status 400 and include
invalid_email_syntaxin the response body. This lets clients understand the exact problem without guesswork. - Reject invalid input early and cleanly. Never silently accept or process malformed emails. Early validation prevents wasted API calls, improves debugging, and keeps logs meaningful—especially when processing large batches via a real-time verification API.
Why Early Validation Matters
Without upfront checks, malformed emails can slip through, leading to noisy logs, unnecessary verification attempts, and false positives in deliverability metrics. A strict schema ensures only well-formed input reaches your backend, making system behavior predictable.
For deeper insight into email delivery mechanics, refer to RFC 5322, the standard governing email format. While it doesn’t cover validation in APIs, it’s the authoritative source for email structure.
When building email verification systems—especially at scale—consider how validation errors impact downstream processes. A single uncaught typo can trigger a cascade of false results. Consistent input handling helps maintain sender reputation and avoid unintended interactions with mail servers, such as those flagged by Spamhaus or MxToolbox due to poor data hygiene.
Using OpenAPI to Document List Hygiene Logic for Bulk Verification
You define success and error responses in OpenAPI for email verification by returning a 200 OK status with a top-level JSON object containing results (an array of verified email objects), processed, total, and errors for metadata, plus a summary object that breaks down counts by verdict—valid, invalid, risky, catch-all. This structure lets clients understand list hygiene at a glance without parsing raw arrays.
Top-Level Response Structure for Bulk Verification
When your OpenAPI endpoint processes a bulk email list, always return a 200 OK status—even if some emails fail. This signals that the request was received and processed successfully, which is standard in RESTful design. The response body should include a results array where each item follows the same schema: email, verdict, and optionally reason or confidence.
Include a metadata block with total (the original list size), processed (how many were checked), and errors (the number of verification failures due to malformed input or network issues). These fields help users spot data quality issues before diving into individual results—like an early warning system for invalid addresses or connection timeouts.
Summary Counts for List Hygiene Insights
Add a summary object with counts for each verdict: valid, invalid, risky, and catch-all. This lets automated systems or analytics dashboards quickly assess list health. For example, a high count of catch-all emails may indicate low signal-to-noise, reducing deliverability. Bulk verification tools like ours use this model to surface risks at scale.
Industry standards—such as those outlined in RFC 5322 for email syntax and RFC 6593 for greylisting—reinforce the need for clear, consistent error modeling. A well-defined OpenAPI schema helps clients handle errors gracefully: a catch-all verdict doesn't mean an email is fake, just that it doesn't reject based on MX or SMTP. Treat it as a risk signal, not a death sentence.
Use application/json as the content type. Avoid mixing response codes like 400 for partial failures—these break client expectations and reduce observability. Instead, use 200 with meaningful metadata. This pattern is proven in delivery platforms like SendGrid and Mailgun, where bulk operations return success with detailed summaries.
How Emaillistchecker.io Handles Verdicts and Response Codes
Our OpenAPI responses use 200 OK for every verified email—whether valid, catch-all, risky, or invalid—to keep integration simple. The status field tells you the verdict, while confidence and reason give you the details to act on. You get consistent data, no matter the result.
Clear Verdicts, Transparent Signals
Every response includes a status value: valid, invalid, catch-all, or risky. This isn’t just labeling—it’s based on real SMTP behavior, DNS checks, and known heuristics from email delivery systems. A valid address reaches the inbox; invalid fails basic syntax or domain checks. catch-all means messages are accepted regardless of recipient, so you’ll get bounces later. risky flags addresses that might be disposable, role-based, or temporarily unavailable.
Each verdict comes with a confidence score from 0.0 to 1.0. Higher scores mean the result is more certain. Confidence helps you filter out uncertain predictions, especially for low-volume campaigns or high-stakes sends. The reason field explains why: "disposable_domain", "role_account", "greylisted", or "no_mx_record" — so you can build custom logic in your app.
API Design for Real-World Use
We don’t overcomplicate errors. No 4xx or 5xx responses for invalid syntax or temporary issues—those are part of the verdict, not HTTP status. This avoids false alarms in monitoring systems. If your client expects HTTP error codes, you’re free to map them later using the response data.
For deeper insight, our inbox placement testing simulates real delivery, showing how your messages land in inboxes over time—especially helpful when testing campaigns with risky or catch-all emails.
The design follows email authentication best practices, similar to those described in RFC 5321, which defines how mail servers handle delivery rejection and acceptance. It’s a foundation we build on: not every system sees a catch-all the same way, but we give you a reliable signal.
Conclusion: Clean APIs Start with Clear Success and Error Definitions
Defining success and error responses in OpenAPI isn’t just about compliance—it builds trust. When developers know exactly what to expect from every endpoint, integration mistakes drop sharply.
Keep it predictable and consistent
Use 200 for known, expected outcomes. Reserve 4xx for client-side issues like malformed requests. Only use 5xx for actual server failures—never for transient or recoverable conditions.
Model every possible email verdict—valid, invalid, catch-all, risky—explicitly in your schema with consistent fields. This eliminates ambiguity and makes automated handling reliable.
Keep reading
- Bulk email verification and list cleaning: when and how to verify (complete guide)
- Why Email Validation Fails Due to DNS TXT Record Response Delays
- Email Validation Flow with Replay Attack Detection Using Request Fingerprints
- Perl Module for Validating Bulk Email Addresses in Old Batch Processing
- Why SMTP 250 Response Code Doesn't Guarantee Email Delivery
Ready to put this into practice? Emaillistchecker.io verifies emails with 98.9% accuracy — start with 100 free verifications.
Frequently asked questions
What HTTP status code should I use for a valid email?
Use 200 OK. A valid email is a successful outcome, even if it’s risky or catch-all.
Can I return a 404 for an invalid email?
No—404 implies a resource not found. Use 400 Bad Request with a clear error message for invalid formats.
How do I signal a catch-all domain in OpenAPI?
Return a 200 status with `status: "catch-all"` and a confidence score in the response body.
Should risky emails return an error?
No—risky is a valid but high-risk verdict. Return it via 200 OK with a clear `risk_level` field.
What’s the difference between 429 and 500?
429 means you’ve exceeded the rate limit. 500 means a server-side failure. Use 429 for throttling.
How should bulk verification results be structured?
Return a 200 with a `results` array of individual responses and a summary with counts by verdict.
Can I use 200 for all responses including errors?
Only if the error is expected and recoverable (e.g. invalid_email). Use 4xx for client-side mistakes.
Do I need to define every possible error in OpenAPI?
Yes—define at least common ones: 400, 403, 429. Include a generic `ErrorResponse` schema.
What information should be in the error details?
Include `code`, `message`, and `field` if applicable. Avoid raw stack traces in production.
How does OpenAPI help with list hygiene?
It forces consistent structure for verdicts and metadata, enabling automation in filtering invalid, role, or disposable emails.
What’s the role of confidence scores in OpenAPI responses?
They help clients sort or filter results—e.g., flag emails with confidence < 0.8 as risky.
How can I test my OpenAPI response definitions?
Use tools like Swagger UI, Postman, or OpenAPI linters to validate schema and HTTP behavior.