---
title: "Run an on-demand DNS health check"
method: POST
path: "/domains/{id}/dns/check"
tags: ["Domains"]
---

# Run an on-demand DNS health check

`POST /domains/{id}/dns/check`

## Request

- Base URL: `https://api.primitive.dev/v1`
- URL: `https://api.primitive.dev/v1/domains/{id}/dns/check`
- Auth: HTTP bearer

Re-checks the domain's DNS records and persists the result as
the domain's current DNS health state. This is the on-demand
counterpart of the scheduled background checker: the response
mirrors what the checker records, broken down per scope
(`ownership`, `inbound`, `outbound`) with the exact records
inspected and each record's individual status.

Unlike /domains/{id}/verify, this call never promotes an
unverified domain; it only re-evaluates and records health for
an existing claim. Managed (Primitive-operated) domains are
rejected with a validation error because their DNS is not
customer-published.

Rate limited per organization; a `Retry-After` header
accompanies 429 responses.

## Headers

- `Idempotency-Key` string

## Response `200`

DNS health check result

- object
  - `success` true, required
  - `data` DomainDnsHealthCheck, required: Result of a DNS health check, as returned by /domains/{id}/dns/check and recorded as the domain's current health state. The top-level fields summarize the domain overall; `scopes` breaks the same check down per capability.
    - `domain_id` string, uuid, required
    - `key_id` string, uuid: Active outbound DKIM key the outbound scope was checked against, when one exists.
    - `domain` string, required
    - `verified` boolean, required: Whether every required scope is currently verified.
    - `status` 'pending' | 'healthy' | 'degraded' | 'suspended', required: Rollup DNS health state. `pending` means never successfully checked, `healthy` means all required records verified, `degraded` means a previously-verified record has regressed, and `suspended` means the failure persisted long enough that the affected capability was disabled.
    - `checked_at` string, date-time, required
    - `next_check_at` string, date-time, nullable, required: Next scheduled background check, or null when none is planned.
    - `outbound_verified_at` string, date-time, nullable, required: When outbound DNS was first verified, or null if it never has been.
    - `consecutive_failures` integer, required
    - `records` DomainDnsRecord[], required: All records inspected across scopes, each with its own status.
      - `type` 'MX' | 'TXT', required: DNS record type.
      - `name` string, required: DNS-provider host/name value relative to the managed root zone.
      - `fqdn` string, required: Fully-qualified DNS record name.
      - `value` string, required: Exact value to publish.
      - `priority` integer: MX priority. Present only for MX records.
      - `ttl` integer: Suggested TTL in seconds when the API can provide one.
      - `required` true, required
      - `purpose` 'inbound_mx' | 'ownership_verification' | 'spf' | 'dkim' | 'dkim_standby' | 'dmarc' | 'tls_reporting', required
      - `status` 'pending' | 'found' | 'legacy' | 'missing' | 'incorrect' | 'unresolved', required: `legacy` means the MX routes mail to Primitive through a legacy host: mail is delivered and the domain stays healthy, but the record should be updated to `value`. `unresolved` means the DNS lookup itself was inconclusive.
      - `message` string: Short explanation of why this record is needed.
    - `scopes` object, required
      - `ownership` DomainDnsHealthScope, required: Health of one DNS scope: `ownership` (verification TXT), `inbound` (MX), or `outbound` (SPF, DKIM, DMARC, TLS-RPT).
        - `scope` 'ownership' | 'inbound' | 'outbound', required
        - `verified` boolean, required: Whether this scope's required records are currently verified.
        - `status` 'pending' | 'healthy' | 'degraded' | 'suspended', required: Rollup DNS health state. `pending` means never successfully checked, `healthy` means all required records verified, `degraded` means a previously-verified record has regressed, and `suspended` means the failure persisted long enough that the affected capability was disabled.
        - `checked_at` string, date-time, required: When this scope was last checked.
        - `next_check_at` string, date-time, nullable, required: Next scheduled background check, or null when none is planned.
        - `consecutive_failures` integer, required: Number of consecutive failed checks for this scope.
        - `records` DomainDnsRecord[], required: The exact records inspected for this scope, each with its own status.
          - `type` 'MX' | 'TXT', required: DNS record type.
          - `name` string, required: DNS-provider host/name value relative to the managed root zone.
          - `fqdn` string, required: Fully-qualified DNS record name.
          - `value` string, required: Exact value to publish.
          - `priority` integer: MX priority. Present only for MX records.
          - `ttl` integer: Suggested TTL in seconds when the API can provide one.
          - `required` true, required
          - `purpose` 'inbound_mx' | 'ownership_verification' | 'spf' | 'dkim' | 'dkim_standby' | 'dmarc' | 'tls_reporting', required
          - `status` 'pending' | 'found' | 'legacy' | 'missing' | 'incorrect' | 'unresolved', required: `legacy` means the MX routes mail to Primitive through a legacy host: mail is delivered and the domain stays healthy, but the record should be updated to `value`. `unresolved` means the DNS lookup itself was inconclusive.
          - `message` string: Short explanation of why this record is needed.
        - `error` string: Human-readable failure reason when the scope check errored.
      - `inbound` DomainDnsHealthScope, required: Health of one DNS scope: `ownership` (verification TXT), `inbound` (MX), or `outbound` (SPF, DKIM, DMARC, TLS-RPT).
        - `scope` 'ownership' | 'inbound' | 'outbound', required
        - `verified` boolean, required: Whether this scope's required records are currently verified.
        - `status` 'pending' | 'healthy' | 'degraded' | 'suspended', required: Rollup DNS health state. `pending` means never successfully checked, `healthy` means all required records verified, `degraded` means a previously-verified record has regressed, and `suspended` means the failure persisted long enough that the affected capability was disabled.
        - `checked_at` string, date-time, required: When this scope was last checked.
        - `next_check_at` string, date-time, nullable, required: Next scheduled background check, or null when none is planned.
        - `consecutive_failures` integer, required: Number of consecutive failed checks for this scope.
        - `records` DomainDnsRecord[], required: The exact records inspected for this scope, each with its own status.
          - `type` 'MX' | 'TXT', required: DNS record type.
          - `name` string, required: DNS-provider host/name value relative to the managed root zone.
          - `fqdn` string, required: Fully-qualified DNS record name.
          - `value` string, required: Exact value to publish.
          - `priority` integer: MX priority. Present only for MX records.
          - `ttl` integer: Suggested TTL in seconds when the API can provide one.
          - `required` true, required
          - `purpose` 'inbound_mx' | 'ownership_verification' | 'spf' | 'dkim' | 'dkim_standby' | 'dmarc' | 'tls_reporting', required
          - `status` 'pending' | 'found' | 'legacy' | 'missing' | 'incorrect' | 'unresolved', required: `legacy` means the MX routes mail to Primitive through a legacy host: mail is delivered and the domain stays healthy, but the record should be updated to `value`. `unresolved` means the DNS lookup itself was inconclusive.
          - `message` string: Short explanation of why this record is needed.
        - `error` string: Human-readable failure reason when the scope check errored.
      - `outbound` DomainDnsHealthScope: Health of one DNS scope: `ownership` (verification TXT), `inbound` (MX), or `outbound` (SPF, DKIM, DMARC, TLS-RPT).
        - `scope` 'ownership' | 'inbound' | 'outbound', required
        - `verified` boolean, required: Whether this scope's required records are currently verified.
        - `status` 'pending' | 'healthy' | 'degraded' | 'suspended', required: Rollup DNS health state. `pending` means never successfully checked, `healthy` means all required records verified, `degraded` means a previously-verified record has regressed, and `suspended` means the failure persisted long enough that the affected capability was disabled.
        - `checked_at` string, date-time, required: When this scope was last checked.
        - `next_check_at` string, date-time, nullable, required: Next scheduled background check, or null when none is planned.
        - `consecutive_failures` integer, required: Number of consecutive failed checks for this scope.
        - `records` DomainDnsRecord[], required: The exact records inspected for this scope, each with its own status.
          - `type` 'MX' | 'TXT', required: DNS record type.
          - `name` string, required: DNS-provider host/name value relative to the managed root zone.
          - `fqdn` string, required: Fully-qualified DNS record name.
          - `value` string, required: Exact value to publish.
          - `priority` integer: MX priority. Present only for MX records.
          - `ttl` integer: Suggested TTL in seconds when the API can provide one.
          - `required` true, required
          - `purpose` 'inbound_mx' | 'ownership_verification' | 'spf' | 'dkim' | 'dkim_standby' | 'dmarc' | 'tls_reporting', required
          - `status` 'pending' | 'found' | 'legacy' | 'missing' | 'incorrect' | 'unresolved', required: `legacy` means the MX routes mail to Primitive through a legacy host: mail is delivered and the domain stays healthy, but the record should be updated to `value`. `unresolved` means the DNS lookup itself was inconclusive.
          - `message` string: Short explanation of why this record is needed.
        - `error` string: Human-readable failure reason when the scope check errored.
    - `error` string: Human-readable failure reason when the check errored.

## Other responses

- `400`: Invalid request parameters
- `401`: Invalid or missing API key
- `404`: Resource not found
- `409`: The domain's active outbound key changed while the check was running. Nothing was recorded; retry the check.
- `429`: Rate limit exceeded. The `ratelimit-*` headers describe the limiter that rejected this request, with its own limit and window, not the API budget that successful responses report. A limiter that reports only a wait sends `Retry-After` alone.

## Changes

> 32 revisions in range; 1 not diffed.

- **2026-11-03** `bce409c97acb`: 155 warning
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `400`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `401`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `404`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `409`
  - …151 more
  - …this revision’s changelog is incomplete
- **2026-10-21** `0360ea8d4f3d`: 65 warning
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `400`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `401`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `404`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `409`
  - …61 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/primitive/apis/primitive-api/changes/domains/:id/dns/check/post.md)

---

[API](https://skmtc.dev/primitive/apis/primitive-api.md) - [All operations](https://skmtc.dev/primitive/apis/primitive-api/llms.txt) - [OpenAPI document](https://skmtc.dev/primitive/apis/primitive-api/revisions/bce409c97acb?raw)
