Riferimento per sviluppatori

Autenticazione della posta elettronica

API DomScan: Verifica dell'autenticazione e-mail per i record SPF, DMARC e DKIM.

Autenticazione della posta elettronica

Verifica dell'autenticazione e-mail per i record SPF, DMARC e DKIM. Questo endpoint convalida tutti e tre gli standard in una sola richiesta e restituisce un voto di sicurezza (A-C) con raccomandazioni pratiche. Utile per risolvere problemi di recapitabilità e rafforzare la sicurezza.

GET /v1/email-auth Crediti: 3

Parametri di query

Parametro Tipo obbligatorio
domain string obbligatorio
selectors string facoltativo

Campi della risposta

Campo Tipo
domain string
spf object
spf.classification object
spf.classification.status string
spf.classification.reason string
spf.classification.evidence object
spf.classification.evidence.source string
spf.classification.evidence.method string
spf.classification.evidence.observed_at string
spf.classification.evidence.detail string
spf.classification.checked_at string
spf.record string | null
spf.lookup_estimate integer
spf.includes[] string[]
spf.redirect string | null
spf.macros_present boolean
spf.macro_references[] string[]
spf.lookup_walk_count integer
spf.lookup_limit_exceeded boolean
spf.walk[] object[]
spf.walk[] object
spf.walk[].domain string
spf.walk[].depth integer
spf.walk[].record string
spf.walk[].mechanisms[] string[]
spf.walk[].includes[] string[]
spf.walk[].redirect string | null
spf.walk[].direct_lookup_count integer
spf.walk[].total_lookup_count integer
spf.walk[].macros_present boolean
spf.walk[].macro_references[] string[]
spf.walk[].multiple_records integer
spf.walk_errors[] string[]
spf.lookup_tree object
spf.lookup_tree.root_domain string
spf.lookup_tree.node_count integer
spf.lookup_tree.max_depth integer
spf.lookup_tree.cycles_detected[] string[]
spf.lookup_tree.nodes[] object[]
spf.lookup_tree.nodes[] object
spf.lookup_tree.nodes[].domain string
spf.lookup_tree.nodes[].depth integer
spf.lookup_tree.nodes[].status string
spf.lookup_tree.nodes[].direct_lookup_count integer
spf.lookup_tree.nodes[].total_lookup_count integer
spf.lookup_tree.nodes[].includes[] string[]
spf.lookup_tree.nodes[].redirect string | null
spf.lookup_tree.nodes[].mechanisms[] string[]
spf.lookup_tree.nodes[].errors[] string[]
spf.lookup_tree.edges[] object[]
spf.lookup_tree.edges[] object
spf.lookup_tree.edges[].from string
spf.lookup_tree.edges[].to string
spf.lookup_tree.edges[].type string
dkim[] object[]
dkim[] object
dkim[].classification object
dkim[].classification.status string
dkim[].classification.reason string
dkim[].classification.evidence object
dkim[].classification.evidence.source string
dkim[].classification.evidence.method string
dkim[].classification.evidence.observed_at string
dkim[].classification.evidence.detail string
dkim[].classification.checked_at string
dkim[].selector string
dkim[].record string | null
dkim[].key_type string | null
dkim[].key_size integer | null
dkim_audit object
dkim_audit.selectors_checked[] string[]
dkim_audit.selectors_found[] object[]
dkim_audit.selectors_found[] object
dkim_audit.selectors_found[].selector string
dkim_audit.selectors_found[].dns_name string
dkim_audit.selectors_found[].record string | null
dkim_audit.selectors_found[].record_type string | null
dkim_audit.selectors_found[].cname_targets[] string[]
dkim_audit.selectors_found[].provider_hint string | null
dkim_audit.selectors_found[].key_type string | null
dkim_audit.selectors_found[].key_size integer | null
dkim_audit.selectors_found[].valid boolean
dkim_audit.selectors_found[].revoked boolean
dkim_audit.selectors_found[].weak boolean
dkim_audit.selectors_found[].hash_algorithms[] string[]
dkim_audit.selectors_found[].service_type string | null
dkim_audit.selectors_found[].flags[] string[]
dkim_audit.selectors_found[].issues[] string[]
dkim_audit.total_found integer
dkim_audit.providers_detected[] string[]
dkim_audit.valid_selector_count integer
dkim_audit.weak_selector_count integer
dkim_audit.revoked_selector_count integer
bimi object
bimi.classification object
bimi.classification.status string
bimi.classification.reason string
bimi.classification.evidence object
bimi.classification.evidence.source string
bimi.classification.evidence.method string
bimi.classification.evidence.observed_at string
bimi.classification.evidence.detail string
bimi.classification.checked_at string
bimi.exists boolean
bimi.record string | null
bimi.valid boolean
bimi.logo_url string | null
bimi.authority_url string | null
bimi.logo_fetch_ok boolean | null
bimi.logo_http_status integer | null
bimi.logo_content_type string | null
bimi.logo_bytes integer | null
bimi.logo_svg_detected boolean | null
bimi.vmc_present boolean
bimi.vmc_fetched boolean | null
bimi.vmc_http_status integer | null
bimi.vmc_content_type string | null
bimi.vmc_certificate_valid boolean | null
bimi.vmc_subject string | null
bimi.vmc_issuer string | null
bimi.vmc_not_before string | null
bimi.vmc_not_after string | null
bimi.vmc_days_to_expiry integer | null
bimi.vmc_fingerprint_sha256 string | null
bimi.vmc_san_domains[] string[]
bimi.errors[] string[]
dmarc object
dmarc.classification object
dmarc.classification.status string
dmarc.classification.reason string
dmarc.classification.evidence object
dmarc.classification.evidence.source string
dmarc.classification.evidence.method string
dmarc.classification.evidence.observed_at string
dmarc.classification.evidence.detail string
dmarc.classification.checked_at string
dmarc.record string | null
dmarc.tags object
mta_sts object
mta_sts.classification object
mta_sts.classification.status string
mta_sts.classification.reason string
mta_sts.classification.evidence object
mta_sts.classification.evidence.source string
mta_sts.classification.evidence.method string
mta_sts.classification.evidence.observed_at string
mta_sts.classification.evidence.detail string
mta_sts.classification.checked_at string
mta_sts.exists boolean
mta_sts.record string | null
mta_sts.valid boolean
mta_sts.policy_id string | null
mta_sts.policy_fetch_ok boolean
mta_sts.policy_http_status integer | null
mta_sts.mode string | null
mta_sts.max_age integer | null
mta_sts.mx_hosts[] string[]
mta_sts.mx_records[] string[]
mta_sts.policy_matches_mx boolean | null
mta_sts.uncovered_mx[] string[]
mta_sts.errors[] string[]
tls_rpt object
tls_rpt.exists boolean
tls_rpt.record string | null
tls_rpt.valid boolean
tls_rpt.rua[] string[]
tls_rpt.errors[] string[]
client_access object
client_access.provider_hint object
client_access.provider_hint.id string
client_access.provider_hint.name string
client_access.mx_records[] string[]
client_access.services[] object[]
client_access.services[] object
client_access.services[].service string
client_access.services[].host string
client_access.services[].port integer
client_access.services[].source string
client_access.services[].priority integer | null
client_access.services[].weight integer | null
client_access.services[].tls_mode string
client_access.services[].reachable boolean
client_access.services[].tls_negotiated boolean
client_access.services[].starttls_offered boolean | null
client_access.services[].protocol string | null
client_access.services[].cipher string | null
client_access.services[].certificate object
client_access.services[].certificate.subject string
client_access.services[].certificate.issuer string
client_access.services[].certificate.not_before string
client_access.services[].certificate.not_after string
client_access.services[].certificate.days_to_expiry integer
client_access.services[].certificate.expired boolean
client_access.services[].certificate.san_domains[] string[]
client_access.services[].certificate.public_key_type string | null
client_access.services[].certificate.public_key_bits integer | null
client_access.services[].certificate.fingerprint_sha256 string | null
client_access.services[].certificate.hostname_match boolean | null
client_access.services[].certificate.chain_valid boolean
client_access.services[].certificate.chain_error string | null
client_access.services[].chain_depth integer
client_access.services[].error string | null
client_access.reachable_service_count integer
client_access.secure_service_count integer
autodiscover object
autodiscover.provider_hint object
autodiscover.provider_hint.id string
autodiscover.provider_hint.name string
autodiscover.mx_records[] string[]
autodiscover.srv object
autodiscover.srv.autodiscover[] object[]
autodiscover.srv.autodiscover[] object
autodiscover.srv.autodiscover[].priority integer
autodiscover.srv.autodiscover[].weight integer
autodiscover.srv.autodiscover[].port integer
autodiscover.srv.autodiscover[].target string
autodiscover.srv.submission[] object[]
autodiscover.srv.submission[] object
autodiscover.srv.submission[].priority integer
autodiscover.srv.submission[].weight integer
autodiscover.srv.submission[].port integer
autodiscover.srv.submission[].target string
autodiscover.srv.submissions[] object[]
autodiscover.srv.submissions[] object
autodiscover.srv.submissions[].priority integer
autodiscover.srv.submissions[].weight integer
autodiscover.srv.submissions[].port integer
autodiscover.srv.submissions[].target string
autodiscover.srv.imap[] object[]
autodiscover.srv.imap[] object
autodiscover.srv.imap[].priority integer
autodiscover.srv.imap[].weight integer
autodiscover.srv.imap[].port integer
autodiscover.srv.imap[].target string
autodiscover.srv.imaps[] object[]
autodiscover.srv.imaps[] object
autodiscover.srv.imaps[].priority integer
autodiscover.srv.imaps[].weight integer
autodiscover.srv.imaps[].port integer
autodiscover.srv.imaps[].target string
autodiscover.srv.pop3[] object[]
autodiscover.srv.pop3[] object
autodiscover.srv.pop3[].priority integer
autodiscover.srv.pop3[].weight integer
autodiscover.srv.pop3[].port integer
autodiscover.srv.pop3[].target string
autodiscover.srv.pop3s[] object[]
autodiscover.srv.pop3s[] object
autodiscover.srv.pop3s[].priority integer
autodiscover.srv.pop3s[].weight integer
autodiscover.srv.pop3s[].port integer
autodiscover.srv.pop3s[].target string
autodiscover.thunderbird_autoconfig object
autodiscover.thunderbird_autoconfig.subdomain object
autodiscover.thunderbird_autoconfig.subdomain.url string
autodiscover.thunderbird_autoconfig.subdomain.status_code integer | null
autodiscover.thunderbird_autoconfig.subdomain.content_type string | null
autodiscover.thunderbird_autoconfig.subdomain.final_url string | null
autodiscover.thunderbird_autoconfig.subdomain.redirect_count integer
autodiscover.thunderbird_autoconfig.subdomain.incoming[] object[]
autodiscover.thunderbird_autoconfig.subdomain.incoming[] object
autodiscover.thunderbird_autoconfig.subdomain.incoming[].type string
autodiscover.thunderbird_autoconfig.subdomain.incoming[].hostname string
autodiscover.thunderbird_autoconfig.subdomain.incoming[].port integer
autodiscover.thunderbird_autoconfig.subdomain.incoming[].socket_type string
autodiscover.thunderbird_autoconfig.subdomain.incoming[].username string
autodiscover.thunderbird_autoconfig.subdomain.outgoing[] object[]
autodiscover.thunderbird_autoconfig.subdomain.outgoing[] object
autodiscover.thunderbird_autoconfig.subdomain.outgoing[].type string
autodiscover.thunderbird_autoconfig.subdomain.outgoing[].hostname string
autodiscover.thunderbird_autoconfig.subdomain.outgoing[].port integer
autodiscover.thunderbird_autoconfig.subdomain.outgoing[].socket_type string
autodiscover.thunderbird_autoconfig.subdomain.outgoing[].username string
autodiscover.thunderbird_autoconfig.subdomain.error string | null
autodiscover.thunderbird_autoconfig.well_known object
autodiscover.thunderbird_autoconfig.well_known.url string
autodiscover.thunderbird_autoconfig.well_known.status_code integer | null
autodiscover.thunderbird_autoconfig.well_known.content_type string | null
autodiscover.thunderbird_autoconfig.well_known.final_url string | null
autodiscover.thunderbird_autoconfig.well_known.redirect_count integer
autodiscover.thunderbird_autoconfig.well_known.incoming[] object[]
autodiscover.thunderbird_autoconfig.well_known.incoming[] object
autodiscover.thunderbird_autoconfig.well_known.incoming[].type string
autodiscover.thunderbird_autoconfig.well_known.incoming[].hostname string
autodiscover.thunderbird_autoconfig.well_known.incoming[].port integer
autodiscover.thunderbird_autoconfig.well_known.incoming[].socket_type string
autodiscover.thunderbird_autoconfig.well_known.incoming[].username string
autodiscover.thunderbird_autoconfig.well_known.outgoing[] object[]
autodiscover.thunderbird_autoconfig.well_known.outgoing[] object
autodiscover.thunderbird_autoconfig.well_known.outgoing[].type string
autodiscover.thunderbird_autoconfig.well_known.outgoing[].hostname string
autodiscover.thunderbird_autoconfig.well_known.outgoing[].port integer
autodiscover.thunderbird_autoconfig.well_known.outgoing[].socket_type string
autodiscover.thunderbird_autoconfig.well_known.outgoing[].username string
autodiscover.thunderbird_autoconfig.well_known.error string | null
autodiscover.outlook_autodiscover object
autodiscover.outlook_autodiscover.url string
autodiscover.outlook_autodiscover.status_code integer | null
autodiscover.outlook_autodiscover.content_type string | null
autodiscover.outlook_autodiscover.final_url string | null
autodiscover.outlook_autodiscover.redirect_count integer
autodiscover.outlook_autodiscover.auth_required boolean | null
autodiscover.outlook_autodiscover.error string | null
autodiscover.recommended[] object[]
autodiscover.recommended[] object
autodiscover.recommended[].service string
autodiscover.recommended[].host string
autodiscover.recommended[].port integer
autodiscover.recommended[].tls_mode string
autodiscover.recommended[].source string
edge_summary object
edge_summary.relay_configured boolean
edge_summary.evidence_sources[] string[]
edge_summary.spf_lookup_count integer | null
edge_summary.spf_lookup_limit_exceeded boolean
edge_summary.dkim_valid_selector_count integer
edge_summary.dkim_weak_selector_count integer
edge_summary.dkim_revoked_selector_count integer
edge_summary.providers_detected[] string[]
edge_summary.mta_sts_enforced boolean
edge_summary.tls_rpt_configured boolean
edge_summary.bimi_logo_verified boolean | null
edge_summary.vmc_certificate_valid boolean | null
edge_summary.client_access_reachable_services integer | null
edge_summary.client_access_secure_services integer | null
edge_summary.autodiscover_recommendation_count integer | null
provider_selector_recommendations[] object[]
provider_selector_recommendations[] object
provider_selector_recommendations[].provider string
provider_selector_recommendations[].selectors[] string[]
provider_selector_recommendations[].source string
provider_selector_recommendations[].checked_selectors[] string[]
provider_selector_recommendations[].found_selectors[] string[]
provider_selector_recommendations[].missing_selectors[] string[]
grade string | null
checks_unknown integer
score_confidence string
notes[] string[]

Richiesta di esempio

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/email-auth?domain=example.com&selectors=google%2Cselector1%2Csendgrid"
const response = await fetch("https://domscan.net/v1/email-auth?domain=example.com&selectors=google%2Cselector1%2Csendgrid", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/email-auth?domain=example.com&selectors=google%2Cselector1%2Csendgrid",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/email-auth?domain=example.com&selectors=google%2Cselector1%2Csendgrid", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/email-auth?domain=example.com&selectors=google%2Cselector1%2Csendgrid")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "google.com",
  "spf": {
    "record": "v=spf1 include:_spf.google.com ~all",
    "lookup_estimate": 1,
    "includes": [
      "_spf.google.com"
    ],
    "redirect": null,
    "macros_present": false,
    "macro_references": [],
    "lookup_walk_count": 1,
    "lookup_limit_exceeded": false,
    "walk": [
      {
        "domain": "google.com",
        "depth": 0,
        "record": "v=spf1 include:_spf.google.com ~all",
        "mechanisms": [
          "include:_spf.google.com",
          "~all"
        ],
        "includes": [
          "_spf.google.com"
        ],
        "redirect": null,
        "direct_lookup_count": 1,
        "total_lookup_count": 1,
        "macros_present": false,
        "macro_references": [],
        "multiple_records": 1
      }
    ],
    "walk_errors": [],
    "lookup_tree": {
      "root_domain": "google.com",
      "node_count": 1,
      "max_depth": 0,
      "cycles_detected": [],
      "nodes": [
        {
          "domain": "google.com",
          "depth": 0,
          "status": "present",
          "direct_lookup_count": 1,
          "total_lookup_count": 1,
          "includes": [
            "_spf.google.com"
          ],
          "redirect": null,
          "mechanisms": [
            "include:_spf.google.com",
            "~all"
          ],
          "errors": []
        }
      ],
      "edges": [
        {
          "from": "google.com",
          "to": "_spf.google.com",
          "type": "include"
        }
      ]
    }
  },
  "dkim": [
    {
      "selector": "google",
      "record": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A",
      "key_type": "rsa",
      "key_size": 2048
    }
  ],
  "dkim_audit": {
    "selectors_checked": [
      "google",
      "default",
      "selector1",
      "selector2"
    ],
    "selectors_found": [
      {
        "selector": "google",
        "dns_name": "google._domainkey.google.com",
        "record": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A",
        "record_type": "TXT",
        "cname_targets": [],
        "provider_hint": "Google Workspace",
        "key_type": "rsa",
        "key_size": 2048,
        "valid": true,
        "revoked": false,
        "weak": false,
        "hash_algorithms": [
          "sha256"
        ],
        "service_type": "email",
        "flags": [
          "s"
        ],
        "issues": []
      }
    ],
    "total_found": 1,
    "providers_detected": [
      "Google Workspace"
    ],
    "valid_selector_count": 1,
    "weak_selector_count": 0,
    "revoked_selector_count": 0
  },
  "bimi": {
    "exists": true,
    "record": "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem",
    "valid": true,
    "logo_url": "https://example.com/logo.svg",
    "authority_url": "https://example.com/vmc.pem",
    "logo_fetch_ok": true,
    "logo_http_status": 200,
    "logo_content_type": "image/svg+xml",
    "logo_bytes": 2048,
    "logo_svg_detected": true,
    "vmc_present": true,
    "vmc_fetched": true,
    "vmc_http_status": 200,
    "vmc_content_type": "application/x-pem-file",
    "vmc_certificate_valid": true,
    "vmc_subject": "/CN=Example Inc VMC",
    "vmc_issuer": "/CN=Example Issuer",
    "vmc_not_before": "2026-01-01T00:00:00Z",
    "vmc_not_after": "2027-01-01T00:00:00Z",
    "vmc_days_to_expiry": 258,
    "vmc_fingerprint_sha256": "AA:BB:CC:DD",
    "vmc_san_domains": [
      "google.com"
    ],
    "errors": []
  },
  "dmarc": {
    "record": "v=DMARC1; p=reject; rua=mailto:[email protected]",
    "tags": {
      "v": "DMARC1",
      "p": "reject",
      "rua": "mailto:[email protected]"
    }
  },
  "mta_sts": {
    "exists": true,
    "record": "v=STSv1; id=2024010101Z",
    "valid": true,
    "policy_id": "2024010101Z",
    "policy_fetch_ok": true,
    "policy_http_status": 200,
    "mode": "enforce",
    "max_age": 86400,
    "mx_hosts": [
      "*.google.com"
    ],
    "mx_records": [
      "aspmx.l.google.com"
    ],
    "policy_matches_mx": true,
    "uncovered_mx": [],
    "errors": []
  },
  "tls_rpt": {
    "exists": true,
    "record": "v=TLSRPTv1; rua=mailto:[email protected]",
    "valid": true,
    "rua": [
      "mailto:[email protected]"
    ],
    "errors": []
  },
  "client_access": {
    "provider_hint": {
      "id": "google_workspace",
      "name": "Google Workspace"
    },
    "mx_records": [
      "aspmx.l.google.com"
    ],
    "services": [
      {
        "service": "imap",
        "host": "imap.gmail.com",
        "port": 993,
        "source": "provider_default",
        "priority": null,
        "weight": null,
        "tls_mode": "implicit",
        "reachable": true,
        "tls_negotiated": true,
        "starttls_offered": null,
        "protocol": "TLSv1.3",
        "cipher": "TLS_AES_256_GCM_SHA384",
        "certificate": {
          "subject": "/CN=imap.gmail.com",
          "issuer": "/CN=WR2",
          "not_before": "2026-01-01T00:00:00Z",
          "not_after": "2026-07-01T00:00:00Z",
          "days_to_expiry": 70,
          "expired": false,
          "san_domains": [
            "imap.gmail.com"
          ],
          "public_key_type": "EC",
          "public_key_bits": 256,
          "fingerprint_sha256": "CC:DD:EE:FF",
          "hostname_match": true,
          "chain_valid": true,
          "chain_error": null
        },
        "chain_depth": 2,
        "error": null
      }
    ],
    "reachable_service_count": 1,
    "secure_service_count": 1
  },
  "autodiscover": {
    "provider_hint": {
      "id": "google_workspace",
      "name": "Google Workspace"
    },
    "mx_records": [
      "aspmx.l.google.com"
    ],
    "srv": {
      "autodiscover": [],
      "submission": [],
      "submissions": [],
      "imap": [],
      "imaps": [],
      "pop3": [],
      "pop3s": []
    },
    "thunderbird_autoconfig": {
      "subdomain": {
        "url": "https://autoconfig.google.com/mail/config-v1.1.xml?emailaddress=postmaster%40google.com",
        "status_code": 404,
        "content_type": "text/html",
        "final_url": "https://autoconfig.google.com/mail/config-v1.1.xml?emailaddress=postmaster%40google.com",
        "redirect_count": 0,
        "incoming": [],
        "outgoing": [],
        "error": null
      },
      "well_known": {
        "url": "https://google.com/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=postmaster%40google.com",
        "status_code": 200,
        "content_type": "application/xml",
        "final_url": "https://google.com/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=postmaster%40google.com",
        "redirect_count": 0,
        "incoming": [
          {
            "type": "imap",
            "hostname": "imap.gmail.com",
            "port": 993,
            "socket_type": "SSL"
          }
        ],
        "outgoing": [
          {
            "type": "smtp",
            "hostname": "smtp.gmail.com",
            "port": 587,
            "socket_type": "STARTTLS"
          }
        ],
        "error": null
      }
    },
    "outlook_autodiscover": {
      "url": "https://autodiscover.google.com/autodiscover/autodiscover.xml",
      "status_code": 401,
      "content_type": "text/html",
      "final_url": "https://autodiscover.google.com/autodiscover/autodiscover.xml",
      "redirect_count": 0,
      "auth_required": true,
      "error": null
    },
    "recommended": [
      {
        "service": "imap",
        "host": "imap.gmail.com",
        "port": 993,
        "tls_mode": "implicit",
        "source": "provider_default"
      }
    ]
  },
  "edge_summary": {
    "relay_configured": true,
    "evidence_sources": [
      "spf_walk",
      "mail_policies",
      "bimi_audit",
      "dkim_audit",
      "mail_client_access",
      "mail_autodiscover"
    ],
    "spf_lookup_count": 1,
    "spf_lookup_limit_exceeded": false,
    "dkim_valid_selector_count": 1,
    "dkim_weak_selector_count": 0,
    "dkim_revoked_selector_count": 0,
    "providers_detected": [
      "Google Workspace"
    ],
    "mta_sts_enforced": true,
    "tls_rpt_configured": true,
    "bimi_logo_verified": true,
    "vmc_certificate_valid": true,
    "client_access_reachable_services": 1,
    "client_access_secure_services": 1,
    "autodiscover_recommendation_count": 1
  },
  "provider_selector_recommendations": [
    {
      "provider": "Google Workspace",
      "selectors": [
        "google",
        "20230601",
        "20210112"
      ],
      "source": "detected",
      "checked_selectors": [
        "google"
      ],
      "found_selectors": [
        "google"
      ],
      "missing_selectors": [
        "20230601",
        "20210112"
      ]
    }
  ],
  "grade": "A",
  "notes": []
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 429 Troppe richieste
POST /v1/tools/spf/build Crediti: 1

Parametri del corpo

Parametro Tipo obbligatorio
include string[] facoltativo
ip4 string[] facoltativo
ip6 string[] facoltativo
a boolean facoltativo
mx boolean facoltativo
redirect string facoltativo
all string
Valori consentiti passfailsoftfailneutral
obbligatorio

Campi della risposta

Campo Tipo
record string
dns_name string
record_type string
length integer
dns_lookups integer
valid boolean
warnings[] string[]
explanation object

Richiesta di esempio

curl -X POST "https://domscan.net/v1/tools/spf/build" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "include": [
    "_spf.google.com"
  ],
  "ip4": [
    "192.0.2.0/24"
  ],
  "mx": true,
  "all": "softfail"
}'
const response = await fetch("https://domscan.net/v1/tools/spf/build", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "include": [
      "_spf.google.com"
    ],
    "ip4": [
      "192.0.2.0/24"
    ],
    "mx": true,
    "all": "softfail"
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    "https://domscan.net/v1/tools/spf/build",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "include": [
            "_spf.google.com",
        ],
        "ip4": [
            "192.0.2.0/24",
        ],
        "mx": True,
        "all": "softfail",
    },
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "include": [
	    "_spf.google.com"
	  ],
	  "ip4": [
	    "192.0.2.0/24"
	  ],
	  "mx": true,
	  "all": "softfail"
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/tools/spf/build", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/spf/build")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "include" => [
    "_spf.google.com"
  ],
  "ip4" => [
    "192.0.2.0/24"
  ],
  "mx" => true,
  "all" => "softfail"
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "record": "example",
  "dns_name": "example",
  "record_type": "domain",
  "length": 1,
  "dns_lookups": 1,
  "valid": true,
  "warnings": [
    "example"
  ],
  "explanation": {}
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 409 HTTP 409
  • 422 HTTP 422
  • 429 Troppe richieste
POST /v1/tools/spf/validate Crediti: 1

Parametri del corpo

Parametro Tipo obbligatorio
record string facoltativo
domain string facoltativo

Campi della risposta

Campo Tipo
domain string
record string | null
valid boolean
version string | null
mechanisms[] object[]
mechanisms[] object
mechanisms[].qualifier string
mechanisms[].mechanism string
mechanisms[].value string
mechanisms[].description string
dns_lookups integer
max_lookups integer
lookup_limit_exceeded boolean
policy string | null
includes[] string[]
ips[] string[]
issues[] string[]
warnings[] string[]
error string

Richiesta di esempio

curl -X POST "https://domscan.net/v1/tools/spf/validate" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "domain": "example.com",
  "record": "v=spf1 include:_spf.google.com ip4:192.0.2.0/24 ~all"
}'
const response = await fetch("https://domscan.net/v1/tools/spf/validate", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "domain": "example.com",
    "record": "v=spf1 include:_spf.google.com ip4:192.0.2.0/24 ~all"
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    "https://domscan.net/v1/tools/spf/validate",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "domain": "example.com",
        "record": "v=spf1 include:_spf.google.com ip4:192.0.2.0/24 ~all",
    },
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "domain": "example.com",
	  "record": "v=spf1 include:_spf.google.com ip4:192.0.2.0/24 ~all"
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/tools/spf/validate", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/spf/validate")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "domain" => "example.com",
  "record" => "v=spf1 include:_spf.google.com ip4:192.0.2.0/24 ~all"
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "example.com",
  "record": "v=spf1 include:_spf.google.com ip4:192.0.2.0/24 ~all",
  "valid": true,
  "version": "spf1",
  "mechanisms": [
    {
      "qualifier": "+",
      "mechanism": "include",
      "value": "_spf.google.com",
      "description": "Include SPF from _spf.google.com"
    },
    {
      "qualifier": "+",
      "mechanism": "ip4",
      "value": "192.0.2.0/24",
      "description": "IPv4 address/range 192.0.2.0/24"
    },
    {
      "qualifier": "~",
      "mechanism": "all",
      "description": "Default policy: softfail"
    }
  ],
  "dns_lookups": 1,
  "max_lookups": 10,
  "lookup_limit_exceeded": false,
  "policy": "softfail",
  "includes": [
    "_spf.google.com"
  ],
  "ips": [
    "192.0.2.0/24"
  ],
  "issues": [],
  "warnings": []
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 409 HTTP 409
  • 422 HTTP 422
  • 429 Troppe richieste
POST /v1/tools/spf/flatten Crediti: 2

Parametri del corpo

Parametro Tipo obbligatorio
domain string obbligatorio

Campi della risposta

Campo Tipo
domain string
original_record string
flattened_record string
original_lookups integer
flattened_lookups integer
resolved_ips object
resolved_ips.ip4[] string[]
resolved_ips.ip6[] string[]
includes_resolved[] object[]
includes_resolved[] object
includes_resolved[].include string
includes_resolved[].resolved_to[] string[]
warnings[] string[]

Richiesta di esempio

curl -X POST "https://domscan.net/v1/tools/spf/flatten" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "domain": "example.com"
}'
const response = await fetch("https://domscan.net/v1/tools/spf/flatten", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "domain": "example.com"
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    "https://domscan.net/v1/tools/spf/flatten",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "domain": "example.com",
    },
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "domain": "example.com"
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/tools/spf/flatten", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/spf/flatten")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "domain" => "example.com"
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "example.com",
  "original_record": "example",
  "flattened_record": "example",
  "original_lookups": 1,
  "flattened_lookups": 1,
  "resolved_ips": {
    "ip4": [
      "192.0.2.0/24"
    ],
    "ip6": [
      "2001:db8::/32"
    ]
  },
  "includes_resolved": [
    {
      "include": "example",
      "resolved_to": [
        "example"
      ]
    }
  ],
  "warnings": [
    "example"
  ]
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 409 HTTP 409
  • 422 HTTP 422
  • 429 Troppe richieste
POST /v1/tools/dmarc/build Crediti: 1

Parametri del corpo

Parametro Tipo obbligatorio
policy string
Valori consentiti nonequarantinereject
obbligatorio
subdomain_policy string
Valori consentiti nonequarantinereject
facoltativo
percentage integer facoltativo
rua string[] facoltativo
ruf string[] facoltativo
adkim string
Valori consentiti relaxedstrict
facoltativo
aspf string
Valori consentiti relaxedstrict
facoltativo

Campi della risposta

Campo Tipo
record string
dns_name string
record_type string
valid boolean
explanation object

Richiesta di esempio

curl -X POST "https://domscan.net/v1/tools/dmarc/build" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "policy": "quarantine",
  "subdomain_policy": "quarantine",
  "percentage": 100,
  "rua": [
    "mailto:[email protected]"
  ],
  "adkim": "relaxed",
  "aspf": "relaxed"
}'
const response = await fetch("https://domscan.net/v1/tools/dmarc/build", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "policy": "quarantine",
    "subdomain_policy": "quarantine",
    "percentage": 100,
    "rua": [
      "mailto:[email protected]"
    ],
    "adkim": "relaxed",
    "aspf": "relaxed"
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    "https://domscan.net/v1/tools/dmarc/build",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "policy": "quarantine",
        "subdomain_policy": "quarantine",
        "percentage": 100,
        "rua": [
            "mailto:[email protected]",
        ],
        "adkim": "relaxed",
        "aspf": "relaxed",
    },
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "policy": "quarantine",
	  "subdomain_policy": "quarantine",
	  "percentage": 100,
	  "rua": [
	    "mailto:[email protected]"
	  ],
	  "adkim": "relaxed",
	  "aspf": "relaxed"
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/tools/dmarc/build", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/dmarc/build")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "policy" => "quarantine",
  "subdomain_policy" => "quarantine",
  "percentage" => 100,
  "rua" => [
    "mailto:[email protected]"
  ],
  "adkim" => "relaxed",
  "aspf" => "relaxed"
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "record": "example",
  "dns_name": "example",
  "record_type": "domain",
  "valid": true,
  "explanation": {}
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 409 HTTP 409
  • 422 HTTP 422
  • 429 Troppe richieste
POST /v1/tools/dmarc/validate Crediti: 1

Parametri del corpo

Parametro Tipo obbligatorio
record string facoltativo
domain string facoltativo

Campi della risposta

Campo Tipo
domain string
record string | null
valid boolean
version string | null
policy string | null
subdomain_policy string | null
percentage integer
rua[] string[]
ruf[] string[]
adkim string
aspf string
fo string
ri integer
strength string
issues[] string[]
warnings[] string[]
error string

Richiesta di esempio

curl -X POST "https://domscan.net/v1/tools/dmarc/validate" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "domain": "example.com",
  "record": "v=DMARC1; p=quarantine; pct=50; rua=mailto:[email protected]; ruf=mailto:[email protected]"
}'
const response = await fetch("https://domscan.net/v1/tools/dmarc/validate", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "domain": "example.com",
    "record": "v=DMARC1; p=quarantine; pct=50; rua=mailto:[email protected]; ruf=mailto:[email protected]"
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    "https://domscan.net/v1/tools/dmarc/validate",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "domain": "example.com",
        "record": "v=DMARC1; p=quarantine; pct=50; rua=mailto:[email protected]; ruf=mailto:[email protected]",
    },
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "domain": "example.com",
	  "record": "v=DMARC1; p=quarantine; pct=50; rua=mailto:[email protected]; ruf=mailto:[email protected]"
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/tools/dmarc/validate", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/dmarc/validate")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "domain" => "example.com",
  "record" => "v=DMARC1; p=quarantine; pct=50; rua=mailto:[email protected]; ruf=mailto:[email protected]"
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "example.com",
  "record": "v=DMARC1; p=quarantine; pct=50; rua=mailto:[email protected]; ruf=mailto:[email protected]",
  "valid": true,
  "version": "DMARC1",
  "policy": "quarantine",
  "subdomain_policy": null,
  "percentage": 50,
  "rua": [
    "mailto:[email protected]"
  ],
  "ruf": [
    "mailto:[email protected]"
  ],
  "adkim": "relaxed",
  "aspf": "relaxed",
  "fo": "0",
  "ri": 86400,
  "strength": "weak",
  "issues": [],
  "warnings": [
    "DMARC only applies to 50% of messages"
  ]
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 409 HTTP 409
  • 422 HTTP 422
  • 429 Troppe richieste
GET /v1/tools/dkim/check Crediti: 1

Parametri di query

Parametro Tipo obbligatorio
domain string obbligatorio
selector string obbligatorio

Campi della risposta

Campo Tipo
domain string
selector string
dns_name string
exists boolean
valid boolean
record string
version string
key_type string
key_data string
key_size integer
flags[] string[]
hash_algorithms[] string[]
service_type string
issues[] string[]

Richiesta di esempio

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/tools/dkim/check?domain=example.com&selector=google"
const response = await fetch("https://domscan.net/v1/tools/dkim/check?domain=example.com&selector=google", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/tools/dkim/check?domain=example.com&selector=google",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/tools/dkim/check?domain=example.com&selector=google", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/dkim/check?domain=example.com&selector=google")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "example.com",
  "selector": "s1",
  "dns_name": "s1._domainkey.example.com",
  "exists": true,
  "valid": true,
  "record": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmJozfC9DIeQ/D61fUDgQO/UpGyaMcxSRagnXuEbbwljO4pJcrtPIJyYW7Y8dmX3XZh1V+tvL7zhYPAYHhJ2//YGSetg20T1xvyy1s4Mfa3JPKFNvq+HYe2/ag/rz8Cl7I0rn7ET0BQc/iKxiptIlgALWdYBNiQBsLCBRsGjQWzzQh1puVIm2U+LTp9qQq42DVnkTJ/kOT2z2QjYTkGeCU19sjXi04gQu5XV7iXF7IZjLbMxE4OnUWRwlAr4n0H/PRGfuteB5KF/COZZ9fP0HKpIUjF8k5YJsjbKEiPA2sL/vKS90nsvPrWsDguT8mAPxIc2wrvYCDtL/O2fJTMQlwQIDAQAB",
  "version": "DKIM1",
  "key_type": "rsa",
  "key_data": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmJozfC9DIeQ/D61fUDgQO/UpGyaMcxSRagnXuEbbwljO4pJcrtPIJyYW7Y8dmX3XZh1V+tvL7zhYPAYHhJ2//YGSetg20T1xvyy1s4Mfa3JPKFNvq+HYe2/ag/rz8Cl7I0rn7ET0BQc/iKxiptIlgALWdYBNiQBsLCBRsGjQWzzQh1puVIm2U+LTp9qQq42DVnkTJ/kOT2z2QjYTkGeCU19sjXi04gQu5XV7iXF7IZjLbMxE4OnUWRwlAr4n0H/PRGfuteB5KF/COZZ9fP0HKpIUjF8k5YJsjbKEiPA2sL/vKS90nsvPrWsDguT8mAPxIc2wrvYCDtL/O2fJTMQlwQIDAQAB",
  "key_size": 2048,
  "issues": []
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 429 Troppe richieste
GET /v1/tools/dkim/discover Crediti: 2

Parametri di query

Parametro Tipo obbligatorio
domain string obbligatorio

Campi della risposta

Campo Tipo
domain string
selectors_checked[] string[]
selectors_found[] object[]
selectors_found[] object
selectors_found[].selector string
selectors_found[].dns_name string
selectors_found[].exists boolean
selectors_found[].record string | null
selectors_found[].record_type string | null
selectors_found[].cname_targets[] string[]
selectors_found[].key_type string | null
selectors_found[].key_size integer | null
selectors_found[].provider_hint string | null
selectors_found[].valid boolean
selectors_found[].revoked boolean
selectors_found[].weak boolean
selectors_found[].hash_algorithms[] string[]
selectors_found[].service_type string | null
selectors_found[].flags[] string[]
selectors_found[].issues[] string[]
total_found integer
common_providers_detected[] string[]
providers_detected[] string[]
valid_selector_count integer
weak_selector_count integer
revoked_selector_count integer

Richiesta di esempio

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/tools/dkim/discover?domain=example.com"
const response = await fetch("https://domscan.net/v1/tools/dkim/discover?domain=example.com", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/tools/dkim/discover?domain=example.com",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/tools/dkim/discover?domain=example.com", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/tools/dkim/discover?domain=example.com")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "example.com",
  "selectors_checked": [
    "example"
  ],
  "selectors_found": [
    {
      "selector": "default",
      "dns_name": "example",
      "exists": true,
      "record": "example",
      "record_type": "TXT",
      "cname_targets": [
        "example"
      ],
      "key_type": "domain",
      "key_size": 1,
      "provider_hint": "example",
      "valid": true,
      "revoked": false,
      "weak": false,
      "hash_algorithms": [
        "example"
      ],
      "service_type": "domain",
      "flags": [
        "example"
      ],
      "issues": [
        "example"
      ]
    }
  ],
  "total_found": 1,
  "common_providers_detected": [
    "example"
  ],
  "providers_detected": [
    "example"
  ],
  "valid_selector_count": 1,
  "weak_selector_count": 1,
  "revoked_selector_count": 1
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 429 Troppe richieste
GET /v1/email/compliance Crediti: 6

Parametri di query

Parametro Tipo obbligatorio
domain string obbligatorio
selectors string facoltativo
providers string facoltativo

Campi della risposta

Campo Tipo
domain string
status string
score integer
grade string
checks_unknown integer
score_confidence string
provider_readiness object
provider_readiness.google object
provider_readiness.google.provider string
provider_readiness.google.display_name string
provider_readiness.google.status string
provider_readiness.google.dns_visible_status string
provider_readiness.google.requirements[] object[]
provider_readiness.google.requirements[] object
provider_readiness.google.requirements[].id string
provider_readiness.google.requirements[].label string
provider_readiness.google.requirements[].status string
provider_readiness.google.requirements[].severity string
provider_readiness.google.requirements[].category string
provider_readiness.google.requirements[].evidence string
provider_readiness.google.requirements[].recommendation string
provider_readiness.google.verification_required[] string[]
provider_readiness.google.notes[] string[]
provider_readiness.microsoft object
provider_readiness.microsoft.provider string
provider_readiness.microsoft.display_name string
provider_readiness.microsoft.status string
provider_readiness.microsoft.dns_visible_status string
provider_readiness.microsoft.requirements[] object[]
provider_readiness.microsoft.requirements[] object
provider_readiness.microsoft.requirements[].id string
provider_readiness.microsoft.requirements[].label string
provider_readiness.microsoft.requirements[].status string
provider_readiness.microsoft.requirements[].severity string
provider_readiness.microsoft.requirements[].category string
provider_readiness.microsoft.requirements[].evidence string
provider_readiness.microsoft.requirements[].recommendation string
provider_readiness.microsoft.verification_required[] string[]
provider_readiness.microsoft.notes[] string[]
summary object
summary.authentication object
summary.transport object
summary.dns_security object
summary.brand_trust object
action_items[] object[]
action_items[] object
action_items[].priority string
action_items[].category string
action_items[].title string
action_items[].detail string
action_items[].fix string
evidence object
evidence.email_auth object
evidence.dns_security object
proxy object
proxy.configured boolean
proxy.enriched boolean
proxy.checks[] string[]
limitations[] string[]
checked_at string
check_duration_ms integer

Richiesta di esempio

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/email/compliance?domain=example.com&selectors=google%2Cselector1%2Csendgrid&providers=google%2Cmicrosoft"
const response = await fetch("https://domscan.net/v1/email/compliance?domain=example.com&selectors=google%2Cselector1%2Csendgrid&providers=google%2Cmicrosoft", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/email/compliance?domain=example.com&selectors=google%2Cselector1%2Csendgrid&providers=google%2Cmicrosoft",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/email/compliance?domain=example.com&selectors=google%2Cselector1%2Csendgrid&providers=google%2Cmicrosoft", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/email/compliance?domain=example.com&selectors=google%2Cselector1%2Csendgrid&providers=google%2Cmicrosoft")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "domain": "example.com",
  "status": "warn",
  "score": 82,
  "grade": "B",
  "provider_readiness": {
    "google": {
      "provider": "google",
      "display_name": "Google/Gmail bulk sender readiness",
      "status": "pass",
      "dns_visible_status": "pass",
      "requirements": [
        {
          "id": "google_spf",
          "label": "SPF must be configured for bulk senders",
          "status": "pass",
          "severity": "critical",
          "category": "dns",
          "evidence": "SPF policy: softfail",
          "recommendation": "Publish one valid SPF record that covers every approved sending platform."
        },
        {
          "id": "google_alignment",
          "label": "From domain must align with either SPF or DKIM on live messages",
          "status": "unknown",
          "severity": "high",
          "category": "message",
          "evidence": "Alignment requires Authentication-Results from a real sent message",
          "recommendation": "Send a test message and verify SPF or DKIM alignment."
        }
      ],
      "verification_required": [
        "From domain must align with either SPF or DKIM on live messages",
        "Outbound mail must be transmitted over TLS"
      ],
      "notes": [
        "Status is based on DNS-visible controls. Live sending requirements still need message-header and sender-platform verification."
      ]
    },
    "microsoft": {
      "provider": "microsoft",
      "display_name": "Microsoft Outlook.com high-volume sender readiness",
      "status": "pass",
      "dns_visible_status": "pass",
      "requirements": [],
      "verification_required": [
        "DMARC must align with either SPF or DKIM"
      ],
      "notes": [
        "Status is based on DNS-visible controls. Live sending requirements still need message-header and sender-platform verification."
      ]
    }
  },
  "summary": {
    "authentication": {
      "spf": {
        "status": "pass",
        "record": "v=spf1 include:_spf.example.com ~all",
        "policy": "softfail",
        "lookup_count": 3,
        "lookup_limit_exceeded": false
      },
      "dkim": {
        "status": "pass",
        "selectors_checked": [
          "google",
          "selector1",
          "sendgrid"
        ],
        "selectors_found": [
          "google"
        ],
        "valid_selector_count": 1,
        "weak_selector_count": 0,
        "revoked_selector_count": 0,
        "providers_detected": [
          "Google Workspace"
        ]
      },
      "dmarc": {
        "status": "warn",
        "record": "v=DMARC1; p=none; rua=mailto:[email protected]",
        "policy": "none",
        "subdomain_policy": null,
        "percentage": 100,
        "rua": [
          "mailto:[email protected]"
        ],
        "alignment_mode": {
          "spf": null,
          "dkim": null
        }
      }
    },
    "transport": {
      "mta_sts": {
        "status": "pass",
        "mode": "enforce",
        "policy_fetch_ok": true,
        "policy_matches_mx": true
      },
      "tls_rpt": {
        "status": "pass",
        "rua": [
          "mailto:[email protected]"
        ]
      },
      "mx_records": [
        "aspmx.l.google.com"
      ],
      "client_access_secure_services": 1
    },
    "dns_security": {
      "dnssec": "pass",
      "caa": "pass",
      "zone_transfer": "pass",
      "authoritative_consistency": "pass",
      "blacklist": "pass"
    },
    "brand_trust": {
      "bimi": "unknown",
      "vmc": "unknown"
    }
  },
  "action_items": [
    {
      "priority": "medium",
      "category": "authentication",
      "title": "Move DMARC beyond monitoring mode",
      "detail": "DMARC is valid but still uses p=none.",
      "fix": "After reviewing aggregate reports, move to p=quarantine or p=reject."
    }
  ],
  "evidence": {
    "email_auth": {
      "spf": {
        "record": "v=spf1 include:_spf.example.com ~all"
      },
      "dmarc": {
        "record": "v=DMARC1; p=none; rua=mailto:[email protected]"
      }
    },
    "dns_security": {
      "security_score": 86,
      "security_grade": "B"
    }
  },
  "proxy": {
    "configured": true,
    "enriched": true,
    "checks": [
      "spf_walk",
      "mail_policies",
      "dkim_audit",
      "bimi_audit"
    ]
  },
  "limitations": [
    "DNS-visible checks cannot prove live message-level SPF, DKIM, DMARC alignment, RFC 5322 formatting, spam rate, or one-click unsubscribe behavior."
  ],
  "checked_at": "2026-04-26T12:00:00Z",
  "check_duration_ms": 642
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 429 Troppe richieste
POST /v1/email-auth/bulk Crediti: 3/item

Parametri di query

Parametro Tipo obbligatorio
dry_run string
Valori consentiti true
facoltativo

Parametri del corpo

Parametro Tipo obbligatorio
domains string[] obbligatorio
selectors string[] facoltativo

Campi della risposta

Campo Tipo
results[] unknown[]
meta object
meta.total integer
meta.succeeded integer
meta.failed integer
meta.max_items integer
meta.credits_per_item integer
meta.duration_ms integer

Richiesta di esempio

curl -X POST "https://domscan.net/v1/email-auth/bulk" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "domains": [
    "example.com",
    "cloudflare.com"
  ],
  "selectors": [
    "selector1",
    "selector2"
  ]
}'
const response = await fetch("https://domscan.net/v1/email-auth/bulk", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "domains": [
      "example.com",
      "cloudflare.com"
    ],
    "selectors": [
      "selector1",
      "selector2"
    ]
  }),
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.post(
    "https://domscan.net/v1/email-auth/bulk",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "domains": [
            "example.com",
            "cloudflare.com",
        ],
        "selectors": [
            "selector1",
            "selector2",
        ],
    },
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "domains": [
	    "example.com",
	    "cloudflare.com"
	  ],
	  "selectors": [
	    "selector1",
	    "selector2"
	  ]
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/email-auth/bulk", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/email-auth/bulk")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "domains" => [
    "example.com",
    "cloudflare.com"
  ],
  "selectors" => [
    "selector1",
    "selector2"
  ]
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Risposta di esempio

{
  "results": [
    {
      "input": "example",
      "data": {}
    }
  ],
  "meta": {
    "total": 1,
    "succeeded": 1,
    "failed": 1,
    "max_items": 10,
    "credits_per_item": 1,
    "duration_ms": 1
  }
}

Codici di stato HTTP

  • 200 OK
  • 400 Richiesta non valida
  • 401 Non autorizzato
  • 402 Pagamento richiesto
  • 409 HTTP 409
  • 422 HTTP 422
  • 429 Troppe richieste