API Examples

Example scripts from the api-scripts directory for common DMARC Defender API workflows.

Bulk Add Domains

Create multiple domains in one request and print the created domain identifiers.
api-scripts/add-domains.py
from typing import Any

import requests

# Replace with a real bearer API key from your organization settings.
DMARC_DEFENDER_API_KEY = "dd_replace_me.replace_me"

# Update this with the domains you want to import.
DOMAINS_TO_ADD: list[str] = [
  "example.com",
  "mail.example.com",
]

def make_api_request(
  method: str,
  url: str,
  data: dict[str, Any] | None = None,
) -> dict[str, Any]:
  base_url = "https://dmarcdefender.io/api/v1"
  full_url = f"{base_url}{url}"
  headers = {
    "Authorization": f"Bearer {DMARC_DEFENDER_API_KEY}",
    "Content-Type": "application/json",
  }

  if method == "GET":
    response = requests.get(full_url, headers=headers)
  elif method == "POST":
    response = requests.post(full_url, headers=headers, json=data)
  else:
    raise ValueError("Unsupported HTTP method")

  response.raise_for_status()
  return response.json()


def get_organization() -> dict[str, str]:
  response = make_api_request("GET", "/org")
  return response["data"]


def bulk_add_domains(domains: list[str], org_id: str) -> list[dict[str, Any]]:
  response = make_api_request(
    "POST",
    f"/org/{org_id}/domains/bulk",
    {"domains": domains},
  )
  return response["data"]

if __name__ == "__main__":
  organization = get_organization()
  created_domains = bulk_add_domains(DOMAINS_TO_ADD, organization["id"])

  print(f"Created {len(created_domains)} domains for {organization['name']}")
  for domain in created_domains:
    print(domain["name"], domain["id"])

DMARC Install Instructions

Fetch DMARC setup guidance for a single domain and print the recommended DNS record.
api-scripts/setup-instructions.py
from typing import Any
import requests

# Replace with a real bearer API key from your organization settings.
DMARC_DEFENDER_API_KEY = "dd_replace_me.replace_me"

# Replace with the domain id returned by the API.
DOMAIN_NAME = "example.com"

def make_api_request(method: str, url: str) -> dict[str, Any]:
  base_url = "https://dmarcdefender.io/api/v1"
  full_url = f"{base_url}{url}"
  headers = {
    "Authorization": f"Bearer {DMARC_DEFENDER_API_KEY}",
  }

  if method != "GET":
    raise ValueError("Unsupported HTTP method")

  response = requests.get(full_url, headers=headers)
  response.raise_for_status()
  return response.json()


def get_organization() -> dict[str, str]:
  response = make_api_request("GET", "/org")
  return response["data"]

def get_domain(org_id: str, domain_name: str) -> dict[str, Any]:
  response = make_api_request("GET", f"/org/{org_id}/domains?name={domain_name}")
  domains = response["data"]
  if not domains:
    raise ValueError(f"Domain {domain_name} not found in organization {org_id}")
  return domains[0]

def get_domain_setup(domain_id: str, org_id: str) -> dict[str, Any]:
  response = make_api_request("GET", f"/org/{org_id}/domains/{domain_id}/setup")
  return response["data"]

if __name__ == "__main__":
  organization = get_organization()
  domain = get_domain(organization["id"], DOMAIN_NAME)
  setup = get_domain_setup(domain["id"], organization["id"])

  # print("Add or update this DNS record:")
  print("Recommended action (update/create/none):", setup["recommended"]["action"])
  print("host:", setup["recommended"]["hostname"])
  print("type:", setup["recommended"]["recordType"])
  print("ttl:", setup["recommended"]["ttlSeconds"])
  print("value:", setup["recommended"]["value"])

Monitor the health of multiple domains (recommendations/volume/grade)

Iterate over domains and check their monitoring status from the API.
api-scripts/domain-health.py
from typing import Any
import requests

# Replace with a real bearer API key from your organization settings.
DMARC_DEFENDER_API_KEY = "dd_replace_me.replace_me"

def make_api_request(
  method: str,
  url: str,
  data: dict[str, Any] | None = None,
) -> dict[str, Any]:
  base_url = "https://dmarcdefender.io/api/v1"
  full_url = f"{base_url}{url}"
  if method == "GET":
    response = requests.get(full_url, headers={"Authorization": f"Bearer {DMARC_DEFENDER_API_KEY}"})
  elif method == "POST":
    response = requests.post(full_url, headers={"Authorization": f"Bearer {DMARC_DEFENDER_API_KEY}", "Content-Type": "application/json"}, json=data)
  else:
    raise ValueError("Unsupported HTTP method")
  
  if response.status_code >= 400:
    print("API response:", response.status_code, response.text)
    response.raise_for_status()

  return response.json()

def get_organization() -> dict[str, str]:
  response = make_api_request("GET", "/org")
  return response["data"]

def get_domain_by_name(org_id: str, domain_name: str) -> dict[str, Any]:
  response = make_api_request("GET", f"/org/{org_id}/domains?name={domain_name}")
  domains = response["data"]
  return domains[0]

def get_domains(org_id: str) -> list[dict[str, Any]]:
  response = make_api_request("GET", f"/org/{org_id}/domains")
  return response["data"]

def get_domain_health(domain_id: str, org_id: str) -> dict[str, Any]:
  response = make_api_request("GET", f"/org/{org_id}/domains/{domain_id}/health")
  return response["data"]

def get_domain_volume(domain_id: str, org_id: str, days: int) -> dict[str, Any]:
  response = make_api_request("GET", f"/org/{org_id}/domains/{domain_id}/volume?days={days}")
  return response["data"]

if __name__ == "__main__":
  org = get_organization()
  print(f"{org['name']=} {org['id']=}")
  domains = get_domains(org["id"])
  print(f"Found {len(domains)=} domains for {org['name']=}")

  for domain in domains:
    health = get_domain_health(domain["id"], org["id"])
    print(f"{domain['name']=} {health['grade']=} {health['score']['score']=}")
  
    volume = get_domain_volume(domain["id"], org["id"], 30)
    print(f"  Volume: {volume['totalEmails']=} emails in the last 30 days")
    print(f"    DMARC Passes: {volume['dmarcPasses']=}")
    print(f"    DMARC Quarantines: {volume['dmarcQuarantines']=}")
    print(f"    DMARC Rejects: {volume['dmarcRejects']=}")
    print(f"    DMARC Overrides: {volume['dmarcOverrides']=}")

    for rec in health["recommendations"]:
      print(f"  - {rec['title']=} {rec['category']=} {rec['severity']=}")
      print(f"    {rec['description']=}")
      print(f"    {rec['remediation']=  }")
      for doc in rec["docs"]:
        print(f"    Doc: {doc['title']} - {doc['url']}")