---
title: "Audit a domain"
method: GET
path: "/tools/audit"
tags: ["Tool"]
---

# Audit a domain

`GET /tools/audit`

## Request

- Base URL: `https://api.palisade.email`
- URL: `https://api.palisade.email/tools/audit`
- Auth: one of:
  - none
  - HTTP bearer
  - HTTP basic

Run the full email-authentication audit against a domain from live DNS: MX, SPF, DKIM, DMARC, BIMI, MTA-STS and TLS-RPT, each scored and annotated, plus an overall score out of 100. The domain does not have to be one you have added to Palisade. Results are cached for ten minutes per domain. Authentication is optional. Note that this response predates the API-wide snake_case convention and keeps its original camelCase field names (`mtaSts`, `lookupCount`, `dmarcValue`), so it does not read like the rest of the API.

## Query parameters

- `domain` string, required
- `email` string, email
- `skip_dkim` 'true' | 'false'
- `skip_webhooks` 'true' | 'false'
- `store_scan` 'true' | 'false'
- `utm_source` string

## Headers

- `Palisade-Journey-Id` string, uuid: The website visitor journey this audit belongs to, the same id sent to `POST /attribution/touches`. Read only when the request captures a lead, and ignored rather than rejected when it is missing or malformed.

## Response `200`

Success

- AuditResult
  - `status` 'success' | 'error', required: "success", or "error" when the audit could not run because the domain's nameservers did not resolve or belong to a domain-parking advertiser. On "error" only `summary` is present, with the reason in `summary.errors`.
  - `summary` object, required: The headline: the overall score and one verdict per dimension.
    - `hostname` string, required: The domain audited, as requested.
    - `email` string, required: The `email` query parameter, echoed back. Empty when none was sent, and empty on the `error` status whether or not one was.
    - `parked` boolean, required: True when Palisade has the domain on record as parked. A parked domain should send no mail, so only SPF and DMARC count toward its score.
    - `score` number, required: 0-100: 100 less what each counted dimension loses, as each dimension's `score` reports.
    - `mx` string: The MX verdict, the same value as `mx.status`.
    - `spf` string: The SPF verdict, the same value as `spf.status`.
    - `dkim` string: The DKIM verdict, the same value as `dkim.status`.
    - `dmarc` string: The DMARC verdict, the same value as `dmarc.status`.
    - `bimi` string: The BIMI verdict, the same value as `bimi.status`.
    - `mtaSts` string: The MTA-STS verdict, the same value as `mtaSts.status`.
    - `tlsRpt` string: The TLS-RPT verdict, the same value as `tlsRpt.status`.
    - `errors` string[], required: Why the audit could not run: "ns-error" when the nameservers did not resolve, "ns-for-advertising-domain" when they belong to a domain-parking advertiser. Empty on success.
    - `warnings` string[]: Always empty. Findings are reported on each dimension.
    - `assessments` string[]: Always empty. Findings are reported on each dimension.
  - `nameservers` string[]: The NS records the audit resolved: the domain's own, or its parent's when it has none.
  - `mx` object: The MX check.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `mxPresent` object, required: The MX check as a state: "mx-present" or "mx-missing".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `mxHost` string, required: The name the MX records were read from: the audited domain, or for a subdomain with no nameservers of its own, the parent whose nameservers answered.
    - `mxValue` object[], required: The MX records found, most preferred first.
      - `exchange` string, required: The mail server hostname.
      - `priority` number, required: MX preference. Lower values are tried first.
    - `resolutionFailed` boolean: True when the MX lookup itself failed, so an empty `mxValue` is not evidence of absence.
  - `spf` object: The SPF check, including what the record costs in DNS lookups.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `spfSoftFail` object, required: The SPF record as a state, such as "spf-soft-fail" (ends in `~all`), "spf-closed" (ends in `-all`), "spf-missing", "spf-multiple-records" or "spf-invalid".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `spfValue` string, required: The SPF record evaluated: the redirect target's when the domain uses `redirect=` and that target publishes exactly one record, otherwise the domain's own; every record joined by newlines, longest first, when more than one is published. Empty only when no record was found, a deprecated record type is published, or the domain publishes a single record carrying `redirect=` alongside an `all` mechanism - a record that loops, over-runs the lookup limit or has an unresolved include is still reported here.
    - `lookupCount` number, required: DNS lookups counted from every term RFC 7208 section 4.6.4 charges one for -- `include`, `a`, `mx`, `ptr`, `exists` and `redirect` -- whether or not each one resolved, and whatever qualifier it carries. Over 10 is an SPF permerror. Each term counts once and names the host it queries, includes and redirects are followed recursively wherever they appear, and `ip4`, `ip6` and `all` cost nothing. Two terms are deliberately not charged, because receivers never query them: anything standing to the right of a matching `all`, and a `redirect=` in a record that also carries an `all`, which RFC 7208 section 6.1 says must be ignored.
    - `lookupStructure` object[], required: The DNS lookups the record costs receivers, as a tree: an include or redirect lists what it expands into under `nested`.
      - `type` string, required: The term that costs the lookup: "include", "redirect", "a", "mx", "ptr" or "exists". "expanded-domain" is the name an `exists:` macro expands to, which costs no lookup.
      - `value` string: The operand the term queries, as published rather than resolved -- with one exception: an `include:` or `redirect=` whose macros all resolved reports the substituted name it queried, under the note "macro-expanded" when that name publishes exactly one SPF record, and with `error` when it does not. A bare `a`, `mx` or `ptr` names the domain whose record it stands in, since that is what it queries: the audited domain at the top level, and the included or redirect target inside the subtree belonging to it. Two cases are not a hostname: an `exists:` carrying a macro is the template, and a nested `expanded-domain` node carries the substituted name only when `%{i}`, `%{ir}`, `%{v}` and `%{d}` are the only macros it uses -- any other macro form leaves the term unexpanded, carrying the note "macro-unexpanded" and no nested node; and an `a:`, `mx:` or `ptr:` carrying a macro, such as `a:%{d}`, is the template unexpanded, since only `include:` and `redirect=` operands are put through the macro resolver. A qualifier does not change the operand: `~a:mail.example.com` and `-mx:relay.example.net` name the host each points at, exactly as the unqualified forms do.
      - `nested` unknown[]: The lookups this one expands into, each an SpfLookupNode.
        - unknown
      - `note` string: "loop" for an include or redirect that refers back to a record already being evaluated, "unresolved" when the lookup could not be completed, "macro-expanded" for a term whose operand carried a macro that was substituted, and "macro-unexpanded" for one carrying a macro that cannot be resolved without a live sender. `exists:`, `include:` and `redirect=` can all carry either, and cost one lookup whichever it is -- except that an expanded `include:` or `redirect=` carries no macro note once its target disappoints: "unresolved" when the lookup could not be completed, "loop" when it refers back, "no-txt" alongside `error` when the target returned no TXT records at all, and no note at all -- just `error` -- when the target returned TXT records but not a single SPF record among them. An expanded `exists:` puts the substituted name in a nested `expanded-domain` node; an expanded `include:` or `redirect=` queries the substituted name and reports it as the value.
      - `error` boolean: True when the include or redirect target publishes no single SPF record, or loops. A lookup that could not be completed carries the note "unresolved" and no `error` instead, and a target that returned no TXT records at all carries `error` together with the note "no-txt".
    - `resolutionFailed` boolean: True when the SPF lookup itself failed, for the domain or its `redirect=` target, so what `errors` reports missing is not evidence of absence.
    - `services` unknown[], required: Always empty.
      - unknown
    - `deprecated` boolean, required: True when the domain still publishes the obsolete SPF record type (DNS type 99), which receivers ignore.
    - `ip4Ranges` string[], required: The `ip4:` ranges the record authorizes itself, not counting its includes. Empty when the record could not be evaluated.
    - `ip6Ranges` string[], required: The `ip6:` ranges the record authorizes itself, not counting its includes. Empty when the record could not be evaluated.
    - `ttl` number, nullable, required: TTL of the SPF record in seconds, from the domain's authoritative nameservers. 0 or null when it could not be read.
    - `recommendations` string[], required: Improvements worth making beyond `errors` and `warnings`, as codes such as "dmarc-policy-quarantine", which urges moving on to reject. Usually empty.
  - `dkim` object: The DKIM check, over the selectors Palisade knows to probe.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `hostname` string, required: The domain whose DKIM selectors were checked.
    - `dkimValues` object[], required: Every DKIM record found. Palisade probes only the selectors its catalogue of sending services uses, so a key under any other selector is not found: an empty list is not proof the domain has no DKIM.
      - `record` string, required: The TXT record published at the selector.
      - `selector` string, required: The selector, published at `<selector>._domainkey.<domain>`.
      - `source` string, required: The sending service in Palisade's catalogue that uses this selector.
      - `k` string, required: The key type from `k=`, such as "rsa". Empty when the tag is absent, which means rsa.
      - `p` string, required: The public key from `p=`. Empty when the key is revoked (`p=` with no value) or the tag is missing.
      - `score` number, required: Points this record takes off the DKIM score. 0 when it is sound.
      - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
      - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
      - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
  - `dmarc` object: The DMARC check, which scores the policy and the reporting separately.
    - `hostname` string, required: The domain the DMARC record was read from: the audited domain, or the parent it was found on when the audited domain publishes none.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `setupState` string, required: Whether the record already sends aggregate reports to Palisade: "SETUP" if so, otherwise "NONE".
    - `dmarcClosed` object, required: The policy half as a state: "dmarc-policy-none", "dmarc-policy-quarantine-*" or "dmarc-policy-reject-*" by `pct=` level (low, medium, high or full), "dmarc-missing" or "dmarc-invalid".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `dmarcMonitored` object, required: The reporting half as a state: "dmarc-monitoring-managed" (aggregate reports reach Palisade), "dmarc-monitoring-external" (they go elsewhere), "dmarc-monitoring-missing" or "dmarc-monitoring-invalid".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `records` string[], required: Every `v=DMARC1` record found. More than one is an error: receivers then ignore DMARC.
    - `dmarcValue` string, nullable: The record evaluated. Null when none was found or more than one is published.
    - `ttl` number, nullable, required: TTL of the DMARC record in seconds, from the authoritative nameservers. Null when it could not be read.
    - `tags` object, required: The tags the record sets, parsed. A tag it omits is null, or an empty list.
      - `policy` string, nullable, required: The `p=` policy, lowercased: "none", "quarantine" or "reject".
      - `pct` number, nullable, required: The `pct=` percentage of failing mail the policy applies to. Null when absent, which means 100.
      - `fo` string, nullable, required: The `fo=` failure-reporting option: "0", "1", "d" or "s".
      - `ruaMailto` string[], required: Where aggregate reports go: the `rua=` addresses, without `mailto:`.
      - `rufMailto` string[], required: Where failure reports go: the `ruf=` addresses, without `mailto:`.
      - `adkim` string, nullable, required: The `adkim=` DKIM alignment mode: "r" relaxed or "s" strict. Null when absent, which means relaxed.
      - `aspf` string, nullable, required: The `aspf=` SPF alignment mode: "r" relaxed or "s" strict. Null when absent, which means relaxed.
      - `sp` string, nullable, required: The `sp=` policy for subdomains. Null when absent, in which case subdomains take `p=`.
    - `monitoring` string[], required: Reporting findings, kept apart from `errors`: codes such as "dmarc-missing-rua-tag", which means no aggregate reports are requested.
    - `recommendations` string[], required: Improvements worth making beyond `errors` and `warnings`, as codes such as "dmarc-policy-quarantine", which urges moving on to reject. Usually empty.
    - `viaCname` boolean, required: True when the record is served through a CNAME rather than published directly.
    - `isPalisadeCname` boolean, required: True when that CNAME points at Palisade, which hosts the record.
    - `resolutionFailed` boolean, required: True when the DMARC lookup itself failed, so what `errors` reports missing is not evidence of absence.
  - `bimi` object: The BIMI check, including the logo and certificate the record links to.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `bimiCertified` object, required: The BIMI record as a state: "bimi-certified" (a logo and a certificate), "bimi-uncertified" (a logo without one), "bimi-missing", "bimi-invalid", "bimi-requirements-not-met" (DMARC is not at enforcement), or once the files are checked "bimi-logo-invalid", "bimi-vmc-invalid" or "bimi-vmc-expired".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `bimiValue` string, nullable, required: The record at `default._bimi.<domain>`. Null when none, or more than one, is published.
    - `location` string, nullable, required: The logo URL from `l=`. Null when the tag is absent.
    - `assertion` string, nullable, required: The `a=` value as published, kept verbatim: an `https://` `.pem` URL where the tag carries one, otherwise the literal "self", an empty string, or whatever unusable value was set. A usable URL here is not a verdict on the certificate, because it is not cleared when the record later fails its checks - read `bimiCertified` for that. Null when the tag is absent or was not reached.
    - `recommendations` string[], required: Improvements worth making beyond `errors` and `warnings`, as codes such as "dmarc-policy-quarantine", which urges moving on to reject. Usually empty.
    - `vmcExpiryDate` string, date-time: When the certificate expires, taken from its `validTo`. Present when validation read a `validTo`, or when a cached expiry from an earlier read was reused; absent when the certificate could not be fetched or parsed, even though it was reached.
    - `viaCname` boolean, required: True when the record is served through a CNAME rather than published directly.
    - `isPalisadeCname` boolean, required: True when that CNAME points at Palisade, which hosts the record.
    - `deepValidated` boolean: True when this audit attempted deep validation: fetching the logo, and the certificate when `a=` names one. It is set before those fetches run, so it does not mean either succeeded - read `logoValidation` and `vmcValidation` for that. Absent when the record failed before that step, and when a VMC result checked within the last 24 hours was reused instead of re-reading it.
    - `logoValidation` object: What fetching and checking the logo at `location` found. Present when `deepValidated` is true.
      - `fetched` boolean, required: True when the logo could be downloaded.
      - `valid` boolean, required: True when it passed Palisade's checks for a BIMI SVG.
      - `error` string, nullable, required: Why the logo failed, when it did.
    - `vmcValidation` object: What fetching and checking the certificate at `assertion` found. Present when `deepValidated` is true and `a=` names a certificate.
      - `fetched` boolean, required: True when the certificate file could be downloaded.
      - `valid` boolean, required: True when every certificate check passed. Warnings such as a logo mismatch do not count against it.
      - `certificateCount` number, required: PEM certificates in the file.
      - `chainComplete` boolean, nullable, required: True when the file carries every certificate from the leaf up to a self-signed root. Null until checked.
      - `chainTrusted` boolean, nullable, required: True when the chain, exactly as published, ends in a root Palisade trusts for BIMI. Null until checked.
      - `trustAnchor` string, nullable, required: The trusted root the chain ends in. Null when it is not trusted.
      - `markTypePresent` boolean, nullable, required: True when the certificate carries the BIMI mark-type attribute a VMC or CMC must have. Null until checked.
      - `isVmc` boolean, nullable, required: True when it is a mark certificate, one that embeds a logo; false when it is another kind of certificate; null when it could not be read.
      - `logoMatchesCertificate` boolean, nullable, required: True when the logo at `location` is byte for byte the one embedded in the certificate. Null when they were not compared.
      - `domainCovered` boolean, nullable, required: True when the certificate names the audited domain. Null until checked.
      - `issuer` string, nullable, required: Common name of the certificate's issuer.
      - `subjectCommonName` string, nullable, required: Common name the certificate was issued to.
      - `validFrom` string, nullable, required: Start of the validity period, ISO 8601.
      - `validTo` string, nullable, required: End of the validity period, ISO 8601.
      - `sanDomains` string[], required: The domains the certificate covers, from its subject alternative names.
      - `error` string, nullable, required: Why the certificate failed, when it did.
  - `mtaSts` object: The MTA-STS check. It does not count toward the overall score.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `mtaStsStatus` object, required: The MTA-STS setup as a state: "mta-sts-enforce", "mta-sts-testing", "mta-sts-none-mode", "mta-sts-missing", "mta-sts-dns-only" (a TXT record but no reachable policy), "mta-sts-mx-mismatch" (the policy misses an MX host) or "mta-sts-invalid".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `txtValue` string, nullable, required: The record at `_mta-sts.<domain>`. Null when none, or more than one, is published.
    - `policyFile` string, nullable, required: The policy served at `https://mta-sts.<domain>/.well-known/mta-sts.txt`, verbatim. Null when it could not be fetched.
    - `mode` string, nullable, required: The policy `mode`: "enforce", "testing" or "none". Null when there is no policy to read.
    - `mxEntries` string[], required: The `mx:` patterns the policy covers.
    - `maxAge` number, nullable, required: The policy `max_age` in seconds. Null when there is no readable value.
    - `policyId` string, nullable, required: The `id=` of the TXT record. Senders fetch the policy again when it changes.
  - `tlsRpt` object: The TLS-RPT check. It does not count toward the overall score.
    - `score` number, required: Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.
    - `status` string, required: Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.
    - `assessments` string[], required: What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.
    - `errors` string[], required: Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.
    - `warnings` string[], required: Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.
    - `tlsRptStatus` object, required: The TLS-RPT record as a state: "tls-rpt-present", "tls-rpt-missing" or "tls-rpt-invalid".
      - `status` string, required: The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".
      - `state` string, required: Stable identifier for what was found, safe to branch on. The field holding this object lists its values.
      - `score` number, required: Points this state earns toward its dimension. Unlike the dimension's own `score`, it counts up from 0.
      - `penalties` string[], required: Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.
    - `txtValue` string, nullable, required: The record at `_smtp._tls.<domain>`. Null when none, or more than one, is published.
    - `reportingEndpoints` string[], required: Where TLS failure reports go: the valid `rua=` destinations, each `mailto:` or `https://`.

---

[API](https://skmtc.dev/palisade/apis/palisade-api.md) · [All operations](https://skmtc.dev/palisade/apis/palisade-api/llms.txt) · [OpenAPI document](https://skmtc.dev/palisade/apis/palisade-api/revisions/37b4ae5a7766?raw)
