{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/inboxguard-io/json-schema/inboxguard-io-deliverability-report-schema.json",
  "title": "DeliverabilityReport",
  "description": "Structured deliverability report for a tracked domain (the JSON form of GET /domains/{id}/report). Summarizes the latest scan into a per-check pass/warn/fail status, the top issues, blocklist hit count, and DMARC policy, plus a link to the branded PDF.",
  "x-generated": "2026-11-12",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/inboxguard-io-openapi.json#/components/schemas/DeliverabilityReport",
  "type": "object",
  "properties": {
    "domain": {
      "type": "string",
      "description": "The reported domain."
    },
    "score": {
      "type": [
        "integer",
        "null"
      ],
      "minimum": 0,
      "maximum": 100,
      "description": "Latest overall 0–100 deliverability score (null if not yet scored)."
    },
    "grade": {
      "type": [
        "string",
        "null"
      ],
      "enum": [
        "A",
        "B",
        "C",
        "D",
        "F",
        null
      ],
      "description": "Letter grade for the latest score."
    },
    "scannedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the underlying scan ran (null if none)."
    },
    "generatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "When this report was generated."
    },
    "checks": {
      "type": "array",
      "description": "Per-check rollup. 'not_applicable'/'unverified' are scoring model v3 (2026-08-05) — 'not_applicable' means the check doesn't apply to this domain (excluded from the score, never rendered as a failure); 'unverified' means it couldn't be checked/determined this scan (render as neutral, never pass/fail). Both are absent (never emitted) for a report generated from a pre-v3 scan.",
      "items": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Check key, e.g. spf, dmarc, dkim, mtaSts, tlsRpt, mxTls, bimi, blocklist."
          },
          "label": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pass",
              "warn",
              "fail",
              "unknown",
              "not_applicable",
              "unverified"
            ]
          }
        }
      }
    },
    "issues": {
      "type": "array",
      "description": "Top issues to fix, worst-first. An issue for an 'unverified' check is always severity=info and reads as a verify action, never a confident failure.",
      "items": {
        "$ref": "#/$defs/Issue"
      }
    },
    "blocklistHits": {
      "type": "integer",
      "description": "Number of DNS-blocklist listings detected."
    },
    "dmarcPolicy": {
      "type": [
        "string",
        "null"
      ],
      "description": "Effective DMARC policy (none/quarantine/reject), or null if no DMARC record."
    },
    "scoreSubtitle": {
      "type": [
        "string",
        "null"
      ],
      "description": "e.g. \"80/100 · scored on 65 of 83 applicable points · 1 check unverified\" — explains the score's denominator when a check was not_applicable/undetermined this scan. Null when there's nothing to explain (pre-v3 scan, or nothing excluded)."
    },
    "pdfUrl": {
      "type": "string",
      "format": "uri",
      "description": "Auth-gated URL for the branded one-page PDF (GET /domains/{id}/report.pdf — send your bearer token)."
    }
  },
  "required": [
    "domain",
    "score",
    "grade",
    "generatedAt",
    "checks",
    "issues",
    "blocklistHits",
    "dmarcPolicy",
    "pdfUrl"
  ],
  "$defs": {
    "Issue": {
      "type": "object",
      "description": "One finding inside a check.",
      "properties": {
        "severity": {
          "type": "string",
          "enum": [
            "info",
            "warn",
            "critical"
          ]
        },
        "message": {
          "type": "string"
        }
      },
      "required": [
        "severity",
        "message"
      ]
    }
  }
}