Deliverability Score

Search Documentation

Search across all developer documentation

Deliverability Score

Every verified sending domain gets a Deliverability Score: a number from 0 to 100, a band, the named checks behind it grouped into five pillars, and one task for each thing that needs fixing. Each task says where the fix is done: in SendOps, in your DNS, in your AWS account, or with a third party. DNS tasks carry the exact records to publish.

Two read-only endpoints expose it. Both need api.reports.view and work on every plan.

EndpointReturns
GET /v1/deliverabilityOne row per verified domain, plus org_summary: the organization’s worst domain.
GET /v1/deliverability/{domain}One domain in full: pillars, every check, the ranked tasks and the latest receiver-side check.

Full schemas are in the sidebar under Deliverability. This is a different thing from GET /v1/reports/deliverability, which is a time series of sent, delivered, bounced and complained counts.

Read-only

Running the authentication check, re-checking a domain and marking a task handled are dashboard actions. No endpoint here changes anything.

What a domain returns

  • score: 0–100, the weighted share of the checks that could be decided which passed. Checks that could not be decided (unknown) are left out of the calculation, not counted as zero or as a pass.
  • band: healthy (90 and above), at_risk (70–89) or failing (below 70). Any blocking task forces failing, whatever the number. unassessed means no weighted check could be decided, and score is then null. band_label is the display text (“Healthy”, “At risk”, “Failing”).
  • coverage: how many weighted checks were scored out of total, how many were unknown, and how many were not_applicable. Always read the score together with its coverage. low_confidence is true when fewer than three checks were scored.
  • pillars: authentication (40), reputation (25), compliance (15), hygiene (10) and infrastructure (10). Each has a label, its nominal weight, its own score (null when none of its checks was decided), its coverage, and not_applicable when every check in it is out of scope, for example compliance when you send below every mailbox provider’s volume threshold. When the score and coverage don’t tell the whole story, a pillar also carries a summary: one plain sentence saying why it doesn’t apply (“You send about 4 a day to Outlook; these rules apply only above 5,000 a day to Outlook, Gmail or Yahoo.”) or what its unmeasured checks need and when they will be measured. summary is left out when there is nothing to add.
  • checks: every named check, with status (pass, warn, fail, unknown or not_applicable), what was measured beside the threshold it is judged against, the basis of the measurement, and the source it was read from and when. Compliance checks carry the mailbox provider’s published rule (Microsoft, Google or Yahoo) with its source URL and dates. A warn counts as a pass and carries an advisory task. An unknown check’s basis says what it needs and, where SendOps can know it, when it will be measured.
  • tasks: ranked by severity, then by the weight of the check that owns them. See below.
  • latest_probe: what SendOps’s own receiver saw the last time it received a message from this domain through your SES: SPF, DKIM and DMARC results and every DKIM signature. It confirms the signature; it does not tell you which folder a mailbox provider would put the message in. Null if the domain has never been checked this way.

A check SendOps has no way to measure yet is left out entirely, not reported as unknown: it has no row in checks and no part in the score or coverage, and it appears on its own once it can be measured. Today that applies to the blocklist check and the one-click unsubscribe check (and the provider rules that rely on it). Don’t treat the list of check keys as fixed.

Every failing or warning check points at exactly one task: its own task, or covered_by, the key of a task owned by another check that fixes the same root cause. An unknown check carries the task that would measure it.

Tasks: read where first

whereMeaning
sendopsA change inside SendOps. link is the app path.
dnsPublish the literal records (type, name, value) at your DNS host.
awsA change in your AWS account. link is the AWS console URL.
third_partyDone outside SendOps, AWS and your DNS.

then names a second place when a fix spans two, such as verifying a domain in AWS and then publishing its DKIM records in DNS. severity is blocking (mail is being lost now), important or advisory.

A task with verifies: true closes by itself at the next check once fixed. One with verifies: false cannot be confirmed by SendOps and can only be marked handled in the dashboard, which hides it for 90 days; acknowledged_until is set while that is the case. Task keys are stable, so they are safe to store.

Before the first score

A newly verified domain has no score until its first nightly run. The list shows it with status: not_yet_assessed and null score, coverage and taken_at. GET /v1/deliverability/{domain} answers 202 with status: not_yet_assessed and next_nightly_at. Neither ever returns zeros in place of a score.

The organization summary

org_summary describes the organization as its worst assessed domain (worst band, then lowest score), never an average. It covers every domain, not just the current page, and also counts open and blocking tasks and how many domains are assessed or still waiting. worst_band is unassessed and worst_domain null until some domain has a score.

The list is cursor-paginated over the domains; see Pagination. Task counts leave out tasks marked handled.

When it updates, and how often to poll

Scores are recalculated nightly at 05:40 UTC, and again when someone re-checks a domain in the dashboard. taken_at says when the domain’s current score was taken, and next_nightly_at when the next nightly run is due.

Don’t poll more than once an hour. Between runs nothing changes. A sensible pattern is to read once shortly after 05:40 UTC, and again after you know someone has re-checked a domain.

Example

curl https://api.sendops.dev/v1/deliverability/example.com \
-H "Authorization: Bearer $SENDOPS_API_KEY"

{domain} is the domain name, matched case-insensitively; the domain’s id works too. A domain your organization does not own is a 404. An abridged response:

{
"status": "assessed",
"domain": "example.com",
"taken_at": "2026-10-12T05:40:00Z",
"score": 45,
"band": "failing",
"band_label": "Failing",
"low_confidence": false,
"coverage": { "scored": 18, "total": 20, "unknown": 2, "not_applicable": 12 },
"pillars": [
  {
    "pillar": "compliance",
    "label": "Provider requirements",
    "weight": 15,
    "score": null,
    "not_applicable": true,
    "coverage": { "scored": 0, "total": 0, "unknown": 0, "not_applicable": 11 },
    "summary": "You send about 4 a day to Outlook; these rules apply only above 5,000 a day to Outlook, Gmail or Yahoo."
  }
],
"checks": [
  {
    "key": "ses_dkim_aligned",
    "pillar": "authentication",
    "status": "fail",
    "measured": "signed d=amazonses.com",
    "threshold": "mail signed d=example.com",
    "task": { "key": "ses_dkim_aligned.signed_as_ses" },
    "covered_by": null
  }
],
"tasks": [
  {
    "key": "ses_dkim_aligned.signed_as_ses",
    "check_key": "ses_dkim_aligned",
    "title": "Mail from example.com is signed as amazonses.com, not as example.com",
    "where": "aws",
    "where_label": "In your AWS account",
    "then": "dns",
    "link": "https://us-east-1.console.aws.amazon.com/ses/home?region=us-east-1#/identities",
    "records": [
      { "type": "CNAME", "name": "a1._domainkey.example.com", "value": "a1.dkim.amazonses.com" }
    ],
    "verifies": true,
    "severity": "blocking",
    "acknowledged_until": null
  }
],
"latest_probe": null,
"next_nightly_at": "2026-10-13T05:40:00Z"
}

Errors

StatusWhen
202The domain has no score yet (not_yet_assessed).
403The credential lacks api.reports.view.
404The domain is not one of your organization’s verified domains.
422On the list, a cursor that is invalid or points at a domain that is no longer verified. Start again without it.
  • Deliverability score: what each check and task means, for the person fixing it.
  • MCP Server: the same score for agents, as the deliverability section of sending_readiness_check.
  • Domain Auth (DMARC): the DMARC reports and policy ladder behind several authentication checks.