{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/ffraud-com/json-schema/ffraud-com-email-response-schema.json",
  "title": "EmailResponse",
  "x-generated": "2026-11-09",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/ffraud-com-openapi.json#/components/schemas/EmailResponse",
  "type": "object",
  "required": [
    "request_id",
    "email",
    "normalized_email",
    "domain",
    "did_you_mean",
    "is_disposable",
    "detection_source",
    "safe_domain",
    "valid_format",
    "is_role_address",
    "is_forwarder",
    "is_alias_service",
    "mx_found",
    "mx_records",
    "email_type"
  ],
  "properties": {
    "request_id": {
      "type": "string",
      "description": "The id of this request. Quote it to support to have the check traced. Every address of a batch shares one."
    },
    "email": {
      "type": "string",
      "description": "The address as sent, with outer spaces removed."
    },
    "normalized_email": {
      "type": [
        "string",
        "null"
      ],
      "description": "The address as one mailbox: lowercased, the +tag removed, googlemail.com read as gmail.com and the dots removed on gmail.com. Null when the address is invalid."
    },
    "domain": {
      "type": "string"
    },
    "did_you_mean": {
      "type": [
        "string",
        "null"
      ],
      "description": "The corrected address when the domain is one keystroke from a big provider (john@gmial.com gives john@gmail.com). Changes no other field."
    },
    "is_disposable": {
      "type": "boolean",
      "description": "True for temporary and alias addresses alike; email_type tells them apart."
    },
    "detection_source": {
      "type": "string",
      "enum": [
        "none",
        "safe_domain",
        "alias_provider",
        "alias_provider_mx",
        "database",
        "pattern",
        "mx_host",
        "mx_ip",
        "provider_live",
        "business_mx",
        "cleared",
        "known_spammer",
        "no_mx",
        "reserved",
        "invalid"
      ],
      "description": "The check that decided the answer. no_mx: the domain does not exist or accepts no mail, so the address is invalid."
    },
    "safe_domain": {
      "type": "boolean",
      "description": "A major mail provider on the allow list; never disposable."
    },
    "valid_format": {
      "type": "boolean"
    },
    "is_role_address": {
      "type": "boolean",
      "description": "e.g. admin@, support@, info@"
    },
    "is_forwarder": {
      "type": "boolean",
      "description": "Mail for the domain is passed on to a mailbox somewhere else."
    },
    "is_alias_service": {
      "type": "boolean",
      "description": "The forwarding service gives one person unlimited addresses. The yes or no for an alias."
    },
    "forwarder_service": {
      "type": "string",
      "description": "The name of the forwarding service, when it can be named."
    },
    "mx_found": {
      "type": [
        "boolean",
        "null"
      ],
      "description": "The domain publishes mail servers (MX records). Null when the lookup did not finish."
    },
    "mx_records": {
      "type": "array",
      "maxItems": 4,
      "items": {
        "type": "string"
      },
      "description": "The mail servers, best first."
    },
    "is_known_spammer": {
      "type": "boolean",
      "description": "This exact address was reported for spam or abuse."
    },
    "reason": {
      "type": "string",
      "description": "One sentence a person can read, explaining the answer."
    },
    "email_type": {
      "type": "string",
      "enum": [
        "temp",
        "alias",
        "normal",
        "invalid"
      ],
      "description": "temp (throwaway inbox), alias (forwarding address, unlimited per person), normal or invalid."
    },
    "blocked": {
      "type": "boolean",
      "description": "Keyed calls only: whether the account refuses this address, from its own allow and block lists first, then its dashboard switches. An invalid address is always blocked."
    },
    "allowlisted": {
      "type": "boolean",
      "description": "Keyed calls only: the domain, or one above it, is on the account's allow list."
    },
    "blocklisted": {
      "type": "boolean",
      "description": "Keyed calls only: the domain, or one above it, is on the account's block list."
    },
    "community_blacklisted": {
      "type": "boolean"
    },
    "blacklist_reports": {
      "type": "integer"
    },
    "blacklist_reasons": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}