Oh Dear
Docs/API

DNS Records

The DNS records endpoints let you browse the complete DNS history for any monitor with the DNS check enabled. We track changes to your DNS record types and alert you when anything changes.

You'll need a monitor ID for these endpoints.

Example request:

$ OHDEAR_TOKEN="your API token"
$ curl https://ohdear.app/api/monitors/1/dns-history-items \
    -H "Authorization: Bearer $OHDEAR_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json'

All endpoints below follow the same authentication pattern.

Get a specific DNS history item #

GET /api/monitors/{monitorId}/dns-history-items/{dnsHistoryItemId}

Returns a single DNS history item by its ID.

Here's what the response looks like:

{
  "id": 2,
  "authoritative_nameservers": [
    "ns1.openprovider.nl",
    "ns2.openprovider.be",
    "ns3.openprovider.eu"
  ],
  "dns_records": [
    {
      "host": "freek.dev",
      "ttl": 1017,
      "class": "IN",
      "type": "A",
      "ip": "138.197.187.74"
    },
    {
      "host": "freek.dev",
      "ttl": 4435,
      "class": "IN",
      "type": "MX",
      "pri": 10,
      "target": "aspmx.l.google.com"
    },
    {
      "host": "freek.dev",
      "ttl": 1060,
      "class": "IN",
      "type": "TXT",
      "txt": "v=spf1 include:amazonses.com ..."
    },
    "..."
  ],
  "raw_dns_records": {
    "ns1.openprovider.nl": [
      "freek.dev.\t\t1017\tIN\tA\t138.197.187.74",
      "..."
    ],
    "..."
  },
  "issues": [
    {
      "name": "NameserversAreNotInSync",
      "nameservers": ["ns2.openprovider.be"]
    },
    {
      "name": "DnsRecordValidationIssue",
      "type": "spf_dangerous_all",
      "nameserver": "ns1.openprovider.nl",
      "record": "freek.dev.\t\t1060\tIN\tTXT\t\"v=spf1 include:amazonses.com +all\"",
      "message": "This SPF record ends in \"+all\" (pass all), which authorizes the entire internet to send mail as your domain. Use \"-all\" or \"~all\" instead."
    }
  ],
  "diff_summary": "No changes",
  "created_at": "2021-11-05 16:07:38"
}
  • authoritative_nameservers: the nameservers we queried for your domain
  • dns_records: parsed DNS records grouped by type. Each record includes host, ttl, class, type, and type-specific fields (e.g., ip for A records, target for MX/NS, txt for TXT)
  • raw_dns_records: raw DNS responses from each nameserver
  • issues: array of detected issues (see possible issues below)
  • diff_summary: human-readable summary of changes compared to the previous check
  • created_at: when this check was performed (UTC)

Results are sorted in reverse chronological order -- the first item contains your current DNS records.

List DNS history #

GET /api/monitors/{monitorId}/dns-history-items

Returns a list of DNS history items for a monitor. Each item follows the same shape as the single response above.

Query parameters:

  • filter[created_at] (string, optional) -- only return records created at or after this timestamp in YmdHis format, in UTC (e.g., 20240615000000)

Possible issues #

The issues array can contain these issue types:

  • CouldNotDiscoverNameservers: we couldn't find the authoritative nameservers for your domain
  • CouldNotFindAnyDnsRecords: some nameservers didn't return any records. The affected nameservers are listed in the nameservers property.
  • NameserversAreNotInSync: a nameserver returned different records than the others. The out-of-sync nameservers are listed in the nameservers property.
  • NameserversUnreachable: one or more nameservers couldn't be reached from our DNS checker, for example because of a timeout or network error. Each entry in the unreachable_nameservers property lists the nameserver, a human-readable message, and optional debug information.
  • DnsLookupFailed: DNS lookup failed. The issue includes a message and optional debug information.

The issues above are blocking: when one is present, your DNS check is marked as failed and you get notified.

Record validation findings #

The issues array can also contain advisory findings about the content of individual records (a malformed SPF record, a DMARC record in the wrong place, an MX record pointing at an IP address, ...). These are informational: they do not fail your check and do not trigger notifications. They carry the name DnsRecordValidationIssue and this shape:

  • name: always DnsRecordValidationIssue
  • type: a stable machine-readable identifier for the finding (e.g. spf_dangerous_all, multiple_spf_records, dmarc_wrong_location, ipv6_in_a_record, mx_target_is_ip_address, cname_at_apex, caa_malformed_issue_value)
  • nameserver: the nameserver whose answer the finding applies to
  • record: the exact record the finding is about
  • message: a human-readable explanation of what's wrong and how to fix it

You can safely ignore these if you only care about hard failures: filter the issues array on name == "DnsRecordValidationIssue" to separate advisory findings from blocking issues.

If you use our MCP server, note that the DNS tool's has_issues flag reflects blocking issues only. Advisory findings are reported separately as a validation_warnings count, so a domain can be perfectly healthy (has_issues: false) while still having validation warnings worth a look.

Was this page helpful?

Feel free to reach out via support@ohdear.app or on X via @OhDearApp if you have any other questions. We'd love to help!