{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/ismalicious-com/json-schema/ismalicious-com-mail-scan-response-schema.json",
  "title": "MailScanResponse",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/ismalicious-com-openapi.json#/components/schemas/MailScanResponse",
  "type": "object",
  "required": [
    "verdict",
    "recommendedAction",
    "riskScore",
    "headline",
    "reasons",
    "sender",
    "authentication",
    "links",
    "attachments",
    "contacts",
    "injection",
    "coverage",
    "latencyMs"
  ],
  "properties": {
    "attachments": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailAttachment"
      }
    },
    "authentication": {
      "$ref": "#/$defs/MailAuthentication"
    },
    "connectingIp": {
      "oneOf": [
        {
          "type": "null"
        },
        {
          "$ref": "#/$defs/MailConnectingIp"
        }
      ]
    },
    "contacts": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailContact"
      },
      "description": "Addresses and numbers written in the body."
    },
    "coverage": {
      "$ref": "#/$defs/MailCoverage",
      "description": "What was checked and what was not."
    },
    "headline": {
      "type": "string",
      "description": "One sentence a ticket or a chat message can carry."
    },
    "injection": {
      "$ref": "#/$defs/MailInjection"
    },
    "latencyMs": {
      "type": "integer",
      "format": "int64",
      "minimum": 0
    },
    "links": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailLink"
      }
    },
    "reasons": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/MailReason"
      },
      "description": "The strongest findings first."
    },
    "recommendedAction": {
      "type": "string",
      "description": "`quarantine` | `review` | `warn` | `deliver`. `deliver` means no\nobjection from this scan; it never releases a message another engine\nheld."
    },
    "riskScore": {
      "type": "integer",
      "format": "int32",
      "description": "0-100. 90 and above only for `malicious`.",
      "minimum": 0
    },
    "sender": {
      "$ref": "#/$defs/MailSender"
    },
    "verdict": {
      "type": "string",
      "description": "`malicious` | `suspicious` | `clean` | `inconclusive`. `clean` is a\npositive claim: it needs your own system's DMARC pass, a sender domain\nthe dataset knows as established (among the 100 000 most visited, and\nnot a free mailbox) and every attachment and link vouched for or read.\nA message with nothing against it and no such evidence is\n`inconclusive`: a DMARC pass shows who sent a message, not that they\ncan be trusted."
    }
  },
  "$defs": {
    "MailAttachment": {
      "type": "object",
      "required": [
        "inline",
        "digests",
        "verdict",
        "knownGood",
        "flags"
      ],
      "properties": {
        "contentType": {
          "type": [
            "string",
            "null"
          ]
        },
        "detectedType": {
          "type": [
            "string",
            "null"
          ],
          "description": "What the bytes are, for a message sent raw: `pe`, `elf`, `macho`, `lnk`,\n`zip`, `ooxml`, `jar`, `ole`, `pdf`, `rtf`, `html`, `text`, `image`,\n`gzip`, `rar`, `7z`, `cab`, `iso` or `unknown`. Absent for a message\nthat came as metadata and digests."
        },
        "digests": {
          "$ref": "#/$defs/MailDigests"
        },
        "family": {
          "type": [
            "string",
            "null"
          ]
        },
        "filename": {
          "type": [
            "string",
            "null"
          ]
        },
        "flags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "From the name and the declared type: `risky_extension`,\n`double_extension`, `bidi_override`, `type_mismatch`, `archive`. From the\nbytes, for a message sent raw: `disguised_program`, `macro_project`,\n`encrypted_archive`, `archive_risky`, `remote_template`,\n`embedded_object`, `pdf_launch`, `pdf_script`, `html_smuggling`,\n`password_form`, `svg_script`, `command_line`. `attached_message` marks a\n`message/rfc822` attachment, read as a message of its own."
        },
        "inline": {
          "type": "boolean",
          "description": "Shown inside the body: listed, not looked up."
        },
        "knownGood": {
          "type": "boolean",
          "description": "NSRL knows the file as known software."
        },
        "origin": {
          "type": [
            "string",
            "null"
          ],
          "description": "`attached_message` when the file came out of a `message/rfc822`\nattachment; absent for the message's own attachments."
        },
        "originName": {
          "type": [
            "string",
            "null"
          ],
          "description": "The attached message the file came out of."
        },
        "size": {
          "type": [
            "integer",
            "null"
          ],
          "format": "int64",
          "minimum": 0
        },
        "verdict": {
          "type": "string",
          "description": "What the hash tier says: `malicious` | `suspicious` | `clean` |\n`unknown`. `unknown` is not a safety claim."
        }
      }
    },
    "MailAuthentication": {
      "type": "object",
      "required": [
        "status"
      ],
      "properties": {
        "dkim": {
          "type": [
            "string",
            "null"
          ]
        },
        "dmarc": {
          "type": [
            "string",
            "null"
          ]
        },
        "headerFrom": {
          "type": [
            "string",
            "null"
          ]
        },
        "spf": {
          "type": [
            "string",
            "null"
          ]
        },
        "status": {
          "type": "string",
          "description": "`trusted` when the result below comes from a header you vouched for,\n`unverified` when none did. This scan does not verify SPF, DKIM or\nDMARC itself yet."
        }
      }
    },
    "MailConnectingIp": {
      "type": "object",
      "required": [
        "address",
        "verdict",
        "sources",
        "listed"
      ],
      "properties": {
        "address": {
          "type": "string"
        },
        "listed": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "sources": {
          "type": "integer",
          "minimum": 0
        },
        "verdict": {
          "type": "string",
          "description": "`malicious` | `suspicious` | `clean` | `unknown`."
        }
      }
    },
    "MailContact": {
      "type": "object",
      "required": [
        "value",
        "kind",
        "verdict",
        "reasons"
      ],
      "properties": {
        "kind": {
          "type": "string",
          "description": "`email` | `phone`."
        },
        "reasons": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "value": {
          "type": "string"
        },
        "verdict": {
          "type": "string",
          "description": "`malicious` | `suspicious` | `unknown`."
        }
      }
    },
    "MailCoverage": {
      "type": "object",
      "required": [
        "ran",
        "skipped",
        "truncated"
      ],
      "properties": {
        "ran": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "skipped": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/MailSkipped"
          }
        },
        "truncated": {
          "type": "boolean",
          "description": "A body, a header list, a link list or the attachment list hit a limit."
        }
      }
    },
    "MailDigests": {
      "type": "object",
      "properties": {
        "md5": {
          "type": [
            "string",
            "null"
          ]
        },
        "sha1": {
          "type": [
            "string",
            "null"
          ]
        },
        "sha256": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "MailInjection": {
      "type": "object",
      "required": [
        "score",
        "families",
        "hiddenScore"
      ],
      "properties": {
        "families": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "hiddenScore": {
          "type": "number",
          "format": "double",
          "description": "The same score over text a reader never sees."
        },
        "score": {
          "type": "number",
          "format": "double",
          "description": "Prompt-injection heuristics over the whole body, as `/gate/scan` runs\nthem. 0.0..=1.0."
        }
      }
    },
    "MailLink": {
      "type": "object",
      "required": [
        "url",
        "host",
        "verdict",
        "sources",
        "flags"
      ],
      "properties": {
        "anchorText": {
          "type": [
            "string",
            "null"
          ]
        },
        "flags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "`anchor_mismatch`, `ip_host`, `userinfo`, `punycode`, `mixed_script`,\n`shortener`, `redirect_param`."
        },
        "host": {
          "type": "string"
        },
        "origin": {
          "type": [
            "string",
            "null"
          ],
          "description": "Where the link was found when it is not the message's own text or HTML:\n`attachment` (read out of a file's bytes) or `attached_message`."
        },
        "originName": {
          "type": [
            "string",
            "null"
          ],
          "description": "The attachment or attached message the link was found in."
        },
        "shownDomain": {
          "type": [
            "string",
            "null"
          ],
          "description": "The domain the visible text names, when it is not the target's."
        },
        "sources": {
          "type": "integer",
          "minimum": 0
        },
        "url": {
          "type": "string",
          "description": "As written in the message. Defang it before relaying."
        },
        "verdict": {
          "type": "string",
          "description": "`malicious` | `suspicious` | `clean` | `unknown`."
        }
      }
    },
    "MailPosture": {
      "type": "object",
      "description": "The sender domain's DNS-published mail posture, from the cached aggregate\n([`super::posture`]).",
      "properties": {
        "dmarcPolicy": {
          "type": [
            "string",
            "null"
          ],
          "description": "The DMARC policy that applies: `none` | `quarantine` | `reject`."
        },
        "grade": {
          "type": [
            "string",
            "null"
          ],
          "description": "`A`..`F`, as the report's DNS card grades it."
        },
        "hasDmarc": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "A DMARC record applies to the sender domain: its own, or its\norganizational domain's."
        },
        "hasMx": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "hasSpf": {
          "type": [
            "boolean",
            "null"
          ]
        },
        "spfAll": {
          "type": [
            "string",
            "null"
          ],
          "description": "The qualifier of the SPF record's `all`: `fail` | `softfail` |\n`neutral` | `pass`. Absent without an SPF record or without an `all`."
        },
        "spoofable": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Nothing the domain publishes would make a receiver that checks DMARC\nreject a message forged with it: no DMARC record, a `p=none` record, or a\npolicy applied to under half of the failing mail. Absent when the DNS\nanswer cannot say."
        }
      }
    },
    "MailReason": {
      "type": "object",
      "required": [
        "code",
        "severity",
        "summary"
      ],
      "properties": {
        "code": {
          "type": "string",
          "description": "Stable machine code: `link.listed`, `attachment.double_extension`…"
        },
        "evidence": {
          "type": [
            "string",
            "null"
          ],
          "description": "What it is about; hosts are defanged (`evil[.]test`)."
        },
        "severity": {
          "type": "string",
          "description": "`high` | `medium` | `low` | `info`."
        },
        "summary": {
          "type": "string"
        }
      }
    },
    "MailSender": {
      "type": "object",
      "required": [
        "verdict",
        "freeProvider",
        "disposable",
        "replyTo"
      ],
      "properties": {
        "address": {
          "type": [
            "string",
            "null"
          ]
        },
        "displayName": {
          "type": [
            "string",
            "null"
          ]
        },
        "disposable": {
          "type": "boolean"
        },
        "domain": {
          "type": [
            "string",
            "null"
          ]
        },
        "freeProvider": {
          "type": "boolean"
        },
        "mx": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "The domain publishes MX hosts, from cached DNS; absent when not cached."
        },
        "posture": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "$ref": "#/$defs/MailPosture",
              "description": "The sender domain's published mail posture, from cached DNS."
            }
          ]
        },
        "replyTo": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "returnPath": {
          "type": [
            "string",
            "null"
          ]
        },
        "verdict": {
          "type": "string",
          "description": "What the dataset says about the address and its domain: `malicious` |\n`suspicious` | `unknown`. Never `clean`: the dataset has no allowlist\nfor addresses."
        }
      }
    },
    "MailSkipped": {
      "type": "object",
      "required": [
        "check",
        "reason"
      ],
      "properties": {
        "check": {
          "type": "string"
        },
        "reason": {
          "type": "string"
        }
      }
    }
  }
}