API Reference
Integrate DDMARC into your own systems. Manage domains, retrieve reports, and automate your email authentication workflow over plain JSON and HTTPS.
Base URL and shape
JSON over HTTPS. No envelope on list responses.
X-API-Key, or Authorization: Bearer.
Hourly, pooled per organization.
read, write or admin, per key.
https://api.ddmarc.com/api/v1
Every path on this page already includes the /api/v1 prefix, so a full URL looks like https://api.ddmarc.com/api/v1/domains. All requests must be made over HTTPS.
Authentication
Programmatic access uses an API key. Create and revoke keys in the dashboard under Settings → Organization → API Keys, or through the /api/v1/api-keys endpoints. Keys are shown once at creation and require the Protect plan or higher.
Included from Protect ($29/mo).Start a 14-day trial →See the Protect plan →
X-API-Key: ddmarc_<64 hex characters>
Authorization: Bearer ddmarc_<64 hex characters>
The same Authorization: Bearer header also accepts a short-lived JWT access token from a dashboard sign-in. If both X-API-Key and Authorization are sent, the API key wins. See Authentication for key format, scopes and token lifetimes.
A request and its response
curl -X GET "https://api.ddmarc.com/api/v1/domains?limit=100&offset=0" \ -H "X-API-Key: $DDMARC_API_KEY"
List endpoints return a bare JSON array — there is no data / meta envelope, and resource ids are integers.
[
{
"id": 42,
"domain": "example.com",
"rua_token": "a1b2c3d4e5",
"ruf_token": "f6g7h8i9j0",
"verification_token": "ddmarc-verify-9f3c1a",
"is_verified": true,
"verified_at": "2026-01-15T11:00:00Z",
"dmarc_verified": true,
"spf_verified": true,
"dkim_verified": false,
"admin_email": null,
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-01T08:12:44Z",
"reports_count": 1250,
"last_report_at": "2026-02-01T06:00:00Z"
}
]Every endpoint
Path parameters shown in braces are integers, except {customer_public_id}, which is an opaque string.
Domains
/api/v1/domainsList all domains/api/v1/domainsAdd a new domain/api/v1/domains/{domain_id}Get domain details/api/v1/domains/{domain_id}Remove a domain/api/v1/domains/{domain_id}/dns-checkCheck the domain's live DNS records/api/v1/domains/{domain_id}/verifyVerify domain ownership/api/v1/domains/{domain_id}/rotate-tokenRotate the domain's RUA/RUF tokens/api/v1/domains/{domain_id}/recommendationsGet configuration recommendationsReports
/api/v1/reportsList DMARC aggregate reports/api/v1/reports/{report_id}Get report details/api/v1/reports/stats/summaryGet aggregated report statistics/api/v1/reports/uploadUpload a DMARC report file/api/v1/reports/export/csvExport report records as CSVDashboard analytics
/api/v1/dashboard/statsGet summary statistics/api/v1/dashboard/trendGet authentication trend over time/api/v1/dashboard/geoGet geographic distribution/api/v1/dashboard/heatmapGet volume heatmap data/api/v1/dashboard/protocol-breakdownGet SPF/DKIM pass-rate breakdown/api/v1/dashboard/top-sourcesGet the highest-volume sending sources/api/v1/dashboard/policy-distributionGet policy distribution across domains/api/v1/dashboard/compliance-scorecardGet the per-domain compliance scorecard/dashboard. Most accept an optional domain_id and a days window (1–365, capped to your plan's retention).Senders
/api/v1/sendersList all senders/api/v1/senders/{sender_id}Get sender details/api/v1/senders/{sender_id}Update a sender's category, display name or notes/api/v1/senders/bulkBulk-update senders/api/v1/senders/isp-analyticsGet ISP/provider breakdown statistics/api/v1/senders/ip-trendsGet sender IP behavior trends/api/v1/senders/{sender_id}/reputationGet sender reputation detail/api/v1/senders/{sender_id}/remediationGet suggested remediation for a sendercategory value to PATCH /api/v1/senders/{sender_id}. There are no separate approve or reject endpoints.Failure analysis
/api/v1/failure-analysis/summaryGet failure totals and split by mechanism/api/v1/failure-analysis/root-causesGet classified root causes with fix suggestions/api/v1/failure-analysis/root-causes/by-sourceGet root causes grouped by sending source/api/v1/failure-analysis/sourcesList failing sources/api/v1/failure-analysis/spoof-clustersGet suspected spoofing campaign clusters/api/v1/failure-analysis/by-header-fromGet failures grouped by spoofed From identity/api/v1/failure-analysis/trendGet failure trend over time/api/v1/failure-analysis/resolution-statsGet time-to-resolution statisticsForensic reports
/api/v1/forensic-reportsList forensic (RUF) reports/api/v1/forensic-reports/{report_id}Get forensic report details/api/v1/forensic-reports/statsGet forensic summary statistics/api/v1/forensic-reports/{report_id}Delete a forensic reportDNS monitoring
/api/v1/dns-monitoring/overviewGet DNS monitoring overview for all domains/api/v1/dns-monitoring/healthGet DNS health across all domains/api/v1/dns-monitoring/domains/{domain_id}/historyGet a domain's DNS record history/api/v1/dns-monitoring/domains/{domain_id}/trendsGet a domain's DNS health trend/api/v1/dns-monitoring/domains/{domain_id}/check-nowTrigger an immediate DNS check/api/v1/dns-monitoring/domains/{domain_id}/settingsUpdate a domain's monitoring settingsDNS policy
/api/v1/domains/{domain_id}/policyGet the managed DNS policy for a domain/api/v1/domains/{domain_id}/policyCreate a managed policy/api/v1/domains/{domain_id}/policyUpdate a managed policy/api/v1/domains/{domain_id}/policy/publishPublish the policy to DNS/api/v1/domains/{domain_id}/simulate-policySimulate the impact of a policy changePolicy rollouts
/api/v1/rolloutsList policy rollouts across domains/api/v1/domains/{domain_id}/rolloutGet a domain's rollout status/api/v1/domains/{domain_id}/rolloutCreate a rollout for a domain/api/v1/domains/{domain_id}/rollout/startStart the rollout/api/v1/domains/{domain_id}/rollout/pausePause the rollout/api/v1/domains/{domain_id}/rollout/resumeResume a paused rollout/api/v1/domains/{domain_id}/rollout/skipSkip to the next stage/api/v1/domains/{domain_id}/rollout/rollbackRoll back to the previous stage/api/v1/domains/{domain_id}/rollout/historyGet rollout stage historyAlerts
/api/v1/alertsList alerts/api/v1/alerts/{alert_id}/readMark an alert as read/api/v1/alerts/read-allMark all alerts as read/api/v1/alerts/{alert_id}/snoozeSnooze an alert/api/v1/alerts/rulesList custom alert rules/api/v1/alerts/rulesCreate a custom alert rule/api/v1/alerts/rules/{rule_id}Update a custom alert rule/api/v1/alerts/rules/{rule_id}Delete a custom alert rule/api/v1/alerts/preferencesGet notification preferences/api/v1/alerts/preferencesUpdate notification preferences/api/v1/alerts/webhook/testSend a test webhookTLS-RPT
/api/v1/tls-rptList TLS-RPT reports/api/v1/tls-rpt/{report_id}Get TLS-RPT report details/api/v1/tls-rpt/stats/summaryGet TLS-RPT summary statistics/api/v1/tls-rpt/uploadUpload a TLS-RPT report fileARC monitoring
/api/v1/arc-monitoring/overviewGet ARC monitoring overview/api/v1/arc-monitoring/domains/{domain_id}/chainsList ARC chains for a domain/api/v1/arc-monitoring/chains/{chain_id}Get ARC chain details/api/v1/arc-monitoring/forwardersList known forwarders/api/v1/arc-monitoring/forwardersAdd a trusted forwarderLookalike domains
/api/v1/domains/{domain_id}/lookalikesList detected lookalike domains/api/v1/domains/{domain_id}/lookalikes/scanTrigger a lookalike domain scanAPI keys
/api/v1/api-keysList API keys/api/v1/api-keysCreate an API key/api/v1/api-keys/{key_id}Revoke an API keyTeam
/api/v1/teamList team members/api/v1/team/inviteInvite a team member/api/v1/team/members/{user_id}/roleChange a member's role/api/v1/team/members/{user_id}Remove a team member/api/v1/team/invite/{invitation_id}Revoke a pending invitationActivity
/api/v1/activityList activity log entries/api/v1/activity/actionsList available activity action types/api/v1/activity/export/csvExport the activity log as CSVMSP management
/api/v1/msp/customersList MSP customers/api/v1/msp/customersCreate a new customer/api/v1/msp/customers/{customer_public_id}/detailGet customer details/api/v1/msp/customers/{customer_public_id}Rename a customer or set its domain cap (max_domains)/api/v1/msp/customers/{customer_public_id}Delete a customer/api/v1/msp/customers/{customer_public_id}/domainsEnroll a domain under a customer/api/v1/msp/billingGet MSP billing summary/api/v1/msp/billing/usagePer-customer domain usage/api/v1/msp/brandingGet MSP branding config/api/v1/msp/brandingUpdate MSP branding{customer_public_id}, the customer's opaque public identifier — not an integer id.GET / PATCH /api/v1/alerts/preferences) and fires when an alert is raised. You can send a probe to any URL with POST /api/v1/alerts/webhook/test. See Webhooks for the payload shape, and for the delivery guarantees that do and do not exist today.Rate limiting
API-key requests are metered hourly and pooled across your whole organization, not per key. There is no per-minute limit and no daily cap.
429 with a Retry-After: 3600 header. The API does not emit X-RateLimit-* headers, so do not budget against them — track your own request count, or back off when you see a 429.Errors
| Code | Status | What it means |
|---|---|---|
| 400 | Bad Request | Invalid request parameters |
| 401 | Unauthorized | Missing, invalid or expired API key |
| 403 | Forbidden | Key scope too low, or the feature is not on your plan |
| 404 | Not Found | Resource not found, or not owned by your organization |
| 422 | Unprocessable Entity | Request body or query failed validation |
| 429 | Too Many Requests | Hourly rate limit exceeded; see Retry-After |
| 500 | Internal Error | Server error — quote the request_id to support |
{
"detail": "Invalid API key"
}{
"detail": "Internal server error",
"request_id": "9f2b41c7-..."
}Validation failures (422) use FastAPI's structured form, where detail is an array of field errors, not a string.
Client libraries
DDMARC does not publish official SDKs. The API is plain JSON over HTTPS with a single authentication header, so any HTTP client works — curl, fetch, requests, or your language's equivalent. If you need a generated client, the running API serves its own OpenAPI schema.