Why Parsing Email Verification JSON Responses Matters in Go

You just integrated an email verification API into your Go service. The first response comes back fine — but when you try to unpack it, your app crashes with a panic. Or worse, it runs but silently ignores valid results. It’s not the API’s fault. It’s how you parsed the JSON.

Every time you receive data from an email verification service — like Emaillistchecker.io — you're dealing with raw JSON. If your Go struct doesn’t mirror exactly how that JSON is shaped, you’ll get nils, skipped fields, or runtime panics. Parsing isn’t just about extracting data. It’s about getting it right, every time.

When you’re working with real-time email verification systems, the structure of your Go struct directly affects reliability, scalability, and error resilience. A single mismatched field tag can break a whole verification pipeline. This is why understanding how to parse email verification JSON responses into Go structs isn't just a technical step — it’s a critical part of building trust in your data pipeline.

Key takeaways

  • Using correct struct tags in Go ensures that JSON field keys like "is_valid" map properly to Go struct fields like IsValid.
  • Unexpected JSON response structures from email verification APIs can cause silent data loss or panics if Go structs aren’t designed to handle real-world variations.
  • Validating and testing JSON parsing logic with actual API responses — especially from services like Emaillistchecker.io — is essential to prevent runtime failures in production.

How Emaillistchecker.io's API Returns Verification Data

When you send an email verification request to Emaillistchecker.io’s API, you receive a clean JSON response with structured data: email, result, verdict, score, reason, and domain. This makes parsing the output into a Go struct straightforward and reliable. The result field tells you the core outcome—valid, invalid, catch-all, or risky—while the score gives a confidence level from 0 to 100.

Common Response Fields and Their Meanings

The result key is the most important part of the response. It’s always one of four values: valid (the address is likely deliverable), invalid (the email doesn’t exist or is syntactically flawed), catch-all (the domain accepts all emails, so verification is unreliable), or risky (the email may be problematic due to temporary issues or greylisting).

When result is invalid, the reason field explains why—like disposable, role, or invalid syntax. This helps you decide whether to keep or remove the email from your list. The score field, ranging from 0 to 100, reflects confidence in the result: higher scores mean more certainty.

Using the Data in Go

To parse this JSON into a Go struct, define fields matching the response keys. For example, use string for email and domain, int for score, and string for result and reason. You can use standard Go libraries like encoding/json to unmarshal the response. This approach works well even for bulk verifications via the API.

Domain-level context is also helpful for spotting patterns. If multiple emails from the same domain return catch-all or risky, it might indicate broader deliverability risks. You can use this insight to adjust your outreach strategy or avoid such domains entirely.

For real-time verification, the JSON structure scales reliably across hundreds or thousands of emails. The consistency of the response format—aligned with industry standards like RFC 5321 and RFC 5322—means you can trust the data without extra validation layers. You can test inbox placement or build integrations with tools like Mailchimp, Klaviyo, or HubSpot through our integrations page.

Understanding how the API structures data enables smoother automation, clearer reporting, and better sender reputation management—especially when paired with tools like bulk verification or inbox placement testing. It’s not just about cleaning lists—it’s about building trustworthy sending practices.

The Core Challenge: Mapping Raw JSON to a Go Struct

You can’t reliably parse an email verification API response into Go structs without matching the JSON field names exactly—either using camelCase or snake_case in your struct tags. If the keys don’t align, json.Unmarshal silently ignores fields, leaving your app with empty data, especially when processing bulk results from services like Emaillistchecker.io.

Why Naming Matters: The Hidden Trap in API Responses

Most email verification APIs, including Emaillistchecker.io's verification API, return responses with keys in camelCase—like isValid or reason. Go structs, by convention, use PascalCase for exported fields. Without proper struct tags, Go doesn’t know how to map the incoming JSON keys to your fields. This results in zero data after unmarshaling, even if the response is perfectly valid.

For example, a field named IsValid won’t match isValid in the JSON unless you explicitly tag it: json:"isValid". This is a common pitfall when building integrations with bulk verification systems where hundreds of responses arrive simultaneously.

How to Get It Right: Struct Tags and Consistency

Let’s say Emaillistchecker.io returns a response with email_address, is_valid, and check_time—all in snake_case. Your Go struct must reflect that. Use the JSON tags to bridge the gap: json:"email_address", json:"is_valid", and so on.

This isn’t just a naming preference—it’s how the Go standard library works. The encoding/json package treats field names as literal keys unless explicitly mapped. This behavior is defined in the Go language spec and widely documented in official resources.

When processing bulk results via Emaillistchecker.io’s API, consistency is non-negotiable. A single misnamed field tag can cause entire batches to fail silently. That’s why validating your response schema before writing code is critical.

You can avoid this entirely by using tools that auto-generate structs from sample payloads—some of which work well with the structure Emaillistchecker.io returns. But even then, you’ll need to ensure tags are correct.

Pro tip: Always check the API's actual response format, not just its documentation. APIs evolve. A struct that worked last week might fail today due to a key change.

Step-by-Step: Creating a Go Struct for Emaillistchecker.io's JSON Response

You can parse Emaillistchecker.io’s email verification JSON response into a Go struct by defining an exported struct with fields matching the API's keys: email, result, verdict, score, domain, and reason. Use JSON tags like `json:"result"` to map field names correctly, apply `omitempty` to optional fields, and ensure the struct is capitalized for external access. This ensures your code handles real API output reliably.

Map JSON Keys Exactly with Proper Tags

  1. Start by defining a Go struct with exported (capitalized) fields. Use email for the verified email address, result for the overall verification outcome, verdict for the final classification (e.g., valid, invalid), score for the confidence rating, domain for the domain name, and reason for a human-readable explanation if the result is not valid.
  2. Apply the json:"key_name" tag to each field to match the exact key names in the Emaillistchecker.io API response. For example, if the API returns "score" and "reason", use Score int `json:"score"` and Reason string `json:"reason"` to ensure correct unmarshaling. This mapping is essential for accurate data extraction.
  3. Use omitempty on fields like Reason or Score when they might be absent in some responses. This prevents the JSON serializer from including empty or zero values, which can clutter output or cause issues in downstream systems.
  4. Ensure all fields are exported (capitalized) so external packages, such as your API client or CLI tool, can access them. If a field is unexported (lowercase), Go’s JSON package won’t be able to populate it, even if the tag matches.

Use Real-World Verification as a Foundation

When building this struct, refer to actual Emaillistchecker.io API responses—pull a few sample results via their Verification API to confirm the shape of the data. The JSON structure is stable, but minor changes can break parsing. Always validate against live output.

Industry standards like RFC 822 (and later RFCs) govern email format, but your Go struct should reflect the specific API contract, not general rules. This alignment is critical when processing bulk data reliably.

For teams integrating with email verification at scale, consider using Emaillistchecker.io’s integrations with platforms like Mailchimp or HubSpot. A well-structured Go type makes it easier to process results programmatically and feed them into workflows.

Sample Go Struct with Correct JSON Tags for Emaillistchecker.io

You can parse the Emaillistchecker.io API response into a Go struct using fields with precise JSON tags. The struct includes Email, Result, Verdict, Score, Domain, and an optional Reason. Each field matches the JSON output exactly, so unmarshaling works reliably. For example, `json:"result"` ensures the API’s "result" field maps correctly to your struct field.

Field Mapping and Tagging Strategy

Let’s walk through the key fields and their purpose. Email holds the input email address, always a string. Result returns a high-level status like "valid" or "invalid", which is useful for filtering. Verdict gives more detail, such as "catch-all" or "risky", helping you decide whether to keep or skip an address. These labels are consistent with industry-standard email validation outcomes.

The Score is an integer from 0 to 100, representing confidence in the result. A high score generally means the address is deliverable; a low one suggests issues like outdated domains or poor reputation. Domain extracts the domain portion, useful for bulk analysis or filtering by domain. Reason is optional and only present when the API detects a specific issue—like a temporary block or role account—which you can log for debugging.

Example Struct in Practice

Here’s how the full struct looks in Go. This exact structure mirrors the actual Emaillistchecker.io JSON output, so it unmarshals without issues. Use it with json.Unmarshal in your service layer or pipeline.

type VerificationResponse struct {
	Email    string `json:"email"`
	Result   string `json:"result"`
	Verdict  string `json:"verdict"`
	Score    int    `json:"score"`
	Domain   string `json:"domain"`
	Reason   string `json:"reason,omitempty"`
}

You can integrate this with the Emaillistchecker.io Verification API to validate thousands of emails at scale. The API returns consistent, well-documented JSON. For teams using Go, this structure enables reliable, performant validation with minimal runtime overhead. You can also use it with bulk verification for list cleaning or inbox placement testing to verify deliverability before sending.

Always validate responses with the API’s official documentation, available via the API reference. This ensures your struct stays in sync as the endpoint evolves. For more context on email validation standards, see RFC 5321 (SMTP) and RFC 5322 (email format), both maintained by the IETF.

Common Pitfalls When Parsing Email Verification JSON in Go

You’ll hit silent failures, runtime panics, and incorrect data if you skip JSON tags, use lowercase fields, assume all fields exist, or misdeclare types like using string for a numeric score. These are common because Go’s unmarshaler is strict by design. RFC 7159 defines JSON structure, and Go follows it precisely—no room for guesswork. Let’s walk through the real issues you’ll face.

Field Naming and Visibility

  • Missing json tags means the unmarshaler checks field names literally. If your JSON has "email" but your struct uses Email, it skips the field silently—no error, just missing data.
  • Using lowercase fields (e.g. email string) prevents external access and causes unmarshal to ignore them entirely. The Go language specification requires exported fields for JSON marshaling to work.

Type and Optional Field Handling

  • Assuming every field like reason exists leads to panics when the field is omitted. You must use pointers or defaults—*string or string with a nil check.
  • Using string for a score field (e.g. "score": 97) causes unmarshal errors. JSON numbers aren’t strings. Use int or float64 to match the data type.
  • Overlooking field order or naming variance—like status vs. valid—breaks parsing. Always map field names explicitly using json:"field_name".

These bugs don’t show up in tests if your sample JSON is perfect. But real API responses vary. Tools like EmailListChecker’s API return structured data with optional fields, so your struct must reflect that reality. Don’t assume consistency.

Use bulk verification to test how your parser handles edge cases in production-level lists. Real data exposes flaws hidden in sample payloads.

Real-World Example: Processing a Bulk Verification Response

When you send a bulk verification request to Emaillistchecker.io, the API returns a JSON array where each object contains a Result, a Score, and other metadata. You unmarshal this into a Go slice like []VerificationResponse and iterate through it to filter only valid addresses for your campaign. This approach is standard in production systems handling large-scale email validation.

Deserializing the Response

Start by defining a struct that matches the API’s expected response shape. Use json.Unmarshal directly on the result body into a slice of your struct type. This avoids manual parsing and reduces bugs.

For example, if the API response has a top-level array of objects, each with email, result, and score fields, your Go struct should reflect that. The Go standard library handles the mapping cleanly when field names match JSON keys.

Filtering Valid Addresses

After unmarshaling, loop through the slice and check the Result field. Only addresses with Result == "valid" are likely to reach the inbox. invalid means the address doesn't exist; catch-all indicates it accepts all emails (high risk of spam complaints); risky suggests possible issues like temporary outages or high bounce history.

Use a straightforward if resp.Result == "valid" check to filter usable addresses. In high-volume workflows, you may also log or store other verdicts for compliance or analytics — but only valid addresses should enter your sending stack.

For deeper insight into how email verification impacts deliverability, refer to industry standards around sender reputation and domain alignment. Organizations like Return Path and the Messaging, Malware, and Mobile Anti-Abuse Working Group (M3AAWG) publish guidance on email hygiene practices.

If you're running a campaign with 10,000+ contacts, verifying your list before sending can reduce bounce rates and improve inbox placement. Tools like Emaillistchecker.io make this scalable: their bulk verification service supports thousands of emails per batch with consistent accuracy.

Once you have a clean list, you can integrate with platforms like Mailchimp or Klaviyo via their API integrations, ensuring your sender reputation stays strong. The same verification logic applies whether you use an API endpoint or a full-scale verification job.

How to Handle Dynamic or Unknown Fields in API Responses

You can safely parse unpredictable or future API responses in Go by using map[string]interface{} for unknown fields, combining it with a static struct for known data, and marking optional fields with json:"omitempty". This approach keeps your code stable even when new fields appear in Emaillistchecker.io’s responses.

Map for Future-Proofing Unknown Response Keys

When verifying email lists via the Emaillistchecker.io API, you can’t always anticipate every field in the JSON response. Future updates might add new status codes, metadata, or flags. To avoid breaking your code, define a catch-all map: map[string]interface{}. This allows you to safely absorb any extra data without type mismatches.

For example, your top-level struct might include a fixed field for email and result, but use Extra map[string]interface{} json:"-" to store anything else. This matches Go’s JSON handling philosophy: if the field isn’t defined in the struct, it’s ignored unless you explicitly capture it.

Optional Fields with omitempty

Some fields—like reason—are useful but not always present. Use json:"reason,omitempty" to ensure they’re only included when set. This reduces noise in logs and APIs, and avoids serialization errors when data is missing. It’s a standard practice for maintainable JSON handling, as seen in the Go specification and widely adopted in production SDKs.

Let’s say the API returns "reason": "invalid_domain" for some entries. Your struct can define Reason string `json:"reason,omitempty"`. If the field is absent in the response, Go will leave it as an empty string—no error, no crash.

Combine both strategies: declare known, critical fields as struct members, and use map[string]any (or map[string]interface{}) for everything else. This is how you build resilient code that can handle schema changes from services like bulk verification or real-time API checks without recompilation.

Verdicts and Scores: What Each Field in the JSON Response Means

You’re parsing an email verification JSON response in Go? The verdicts (valid, invalid, catch-all, risky) and the score (0–100) tell you exactly how safe and deliverable each email is. A score of 90+ means it’s worth sending to; below 70, and you’re risking bounces or spam complaints. Let’s break down what each field actually means in practice.

Core Response Fields Explained

  • valid: The email is syntactically correct, the domain exists, and the mail server accepts messages for this address. This is your green light. You can send to it with confidence.
  • invalid: The email is malformed (e.g., missing @ or domain), or the domain doesn’t exist. There’s no point sending to it. It will bounce.
  • catch-all: The domain accepts all emails, even invalid ones. You can’t verify a specific address this way. Sending to a catch-all risks appearing as spam — common with free domains or overly permissive mail servers.
  • risky: The address has a low deliverability score, often due to past bounces, suspicious patterns, or poor sender reputation. Even if it’s technically valid, it’s likely to land in spam or get rejected. Use caution.
  • score: A numeric value from 0 to 100 measuring the likelihood of successful delivery. We recommend only sending to emails with a score of 90 or higher. Scores below 70 are high-risk.

What This Means for Your Go Application

When you map the JSON response into a Go struct, use these verdicts and scores not just as flags — use them to build decision logic. A Score of 90+ means you can proceed; Risky means skip or flag for review. Catch-all domains must be filtered out entirely.

For example, if you're building a campaign tool, filter out invalid and risky addresses before sending. Use catch-all as a signal to pause or investigate. Always respect the score threshold — it’s based on real-time delivery data, including feedback from ISPs like Gmail and Yahoo.

Real-world delivery performance shows that lists with a median score above 90 see bounce rates under 1% and inbox placement above 93%. You don’t have to guess — the response tells you.

Start with a bulk email verification to clean your list. For real-time validation, use the API. Both return these exact verdicts and scores. If you need to find valid emails, try our email finder before verifying.

Understanding the meaning behind each field is the first step to writing robust, deliverable-first code.

Why Correct JSON Unmarshaling Is Key to Reliable Email List Hygiene

When you parse an email verification response from an API like Emaillistchecker.io’s, a single malformed field or incorrect type can slip invalid or risky emails into your campaigns. This isn’t just a technical hiccup—it directly raises bounce rates, harms sender reputation, and reduces inbox placement. Proper unmarshaling ensures only true “valid” results are processed, which is how you maintain clean lists at scale.

How Bad Parsing Sabotages Deliverability

Let’s say your Go code expects a boolean for valid in the JSON response, but the API returns a string like "true" instead of true. If your struct doesn’t handle that, the unmarshal fails silently or misclassifies the email as invalid. That means real addresses get tossed, while bad ones slip through. Over time, this erodes your sender reputation—email providers like Gmail and Outlook track engagement and bounce behavior over time, and poor list hygiene shows up in their filters.

Even small inconsistencies compound at scale. Processing thousands of emails? A single unescaped field or misdeclared type can lead to crashes or data drift. This isn’t theoretical: the Internet Engineering Task Force’s RFC 822 and RFC 7116 outline standards for email formats and data exchange, and deviations from these norms can trigger rejection or filtering at the receiving end.

Struct Tags and Runtime Safety at Scale

You can avoid this by using precise struct tags. For example, json:"valid" should map exactly to the key in the response. If your API includes "status":"valid", using json:"status" avoids confusion. Misaligned tags cause the Go runtime to skip fields or panic during processing—especially when handling bulk results via Emaillistchecker.io’s Verification API.

Using well-structured Go structs with correct tags doesn’t just prevent crashes. It ensures your system reliably filters out risky addresses like role accounts (admin@, support@), disposable domains, and catch-all setups—common sources of high bounce rates. A clean list means fewer complaints, lower bounce rates, and better inbox placement.

For teams automating list checks, integrating with Emaillistchecker.io’s Bulk Verification or integrations requires confidence in the response format. Misreading one field can disrupt entire workflows. So when you build the parser, treat every field like an edge case—because it might be.

Conclusion: Build a Robust, Scalable Email Verification Flow

When parsing Emaillistchecker.io’s API responses into Go structs, use exact field names and correct JSON tags to ensure the data maps reliably. Omitting or misnaming tags leads to silent failures and inconsistent results.

Always validate the presence and type of each field after parsing—check for empty strings, unexpected nulls, or incorrect data types. This prevents crashes in production and ensures downstream systems receive clean input.

Integrate this validation step into your email list hygiene pipeline. Consistently removing invalid or risky addresses reduces bounce rates, protects sender reputation, and improves inbox placement across major providers.

Keep reading

Ready to put this into practice? Emaillistchecker.io verifies emails with 98.9% accuracy — start with 100 free verifications.

Frequently asked questions

What is json.Unmarshal and why do I need it?

json.Unmarshal converts raw JSON data from an API into a Go struct. It's necessary to access structured data from email verification APIs like Emaillistchecker.io.

Why don’t my Go struct fields populate when parsing JSON?

Most likely, the field names don't match the JSON keys. Use `json:"key_name"` tags to map them correctly.

Can I use lowercase struct fields in Go for API parsing?

No. Lowercase fields are unexported and cannot be accessed by `json.Unmarshal` outside their package.

What does `json:"reason,omitempty"` do?

It tells Go to omit the 'reason' field in JSON output if its value is empty, and to ignore it if missing in input.

How do I handle arrays of email verification responses?

Define a slice type like `[]VerificationResponse` and use `json.Unmarshal` with that type to process multiple results.

What should I do if the API adds new fields later?

Use `map[string]any` for unknown fields or update your struct with new tags and `omitempty` to avoid breaking existing code.

Does Emaillistchecker.io return different fields based on the API endpoint?

Yes. The real-time API and bulk API return similar fields, but bulk responses are returned as arrays of objects.

What’s the best way to test if my Go struct unmarshals correctly?

Use a known valid JSON payload from Emaillistchecker.io and run it through `json.Unmarshal` with a test case.

Is it safe to assume all emails will return a score?

No. The 'score' field is present in most responses but may be missing in some outdated or incomplete API outputs.

Can I parse the JSON response without defining a Go struct?

Yes, using `map[string]interface{}` or `[]interface{}` but at the cost of losing type safety and clarity.