---
title: "Add a domain"
method: POST
path: "/domains"
tags: ["Domain"]
---

# Add a domain

`POST /domains`

## Request

- Base URL: `https://api.palisade.email`
- URL: `https://api.palisade.email/domains`
- Auth: one of:
  - HTTP bearer
  - HTTP basic

## Headers

- `Palisade-Version` '2025-04-30' | 'unstable', required

## Request body

- object
  - `url` string, required
  - `group_id` string, uuid
  - `use_stored_scan` boolean

## Response `200`

Success

- object
  - `id` string, uuid, required
  - `url` string, required
  - `dmarc_policy` string, required
  - `dmarc_options` object, required
    - `additional_emails` string[], required
    - `legacy_ruf_emails` string[]
    - `policy` 'none' | 'quarantine' | 'reject', required
    - `pct` number, required
    - `sp` 'none' | 'quarantine' | 'reject' | 'same', required
    - `strict_spf` boolean, required
    - `strict_dkim` boolean, required
  - `spf_options` object, required
    - `force_flattening` boolean, required
    - `enabled` boolean, required
    - `mechanism_descriptions` object
  - `managed_dns_status` object, required
    - `dmarc` 'unknown' | 'syncing' | 'ready' | 'error', required
    - `spf` 'unknown' | 'syncing' | 'ready' | 'error', required
    - `dkim` 'unknown' | 'syncing' | 'ready' | 'error', required
    - `bimi` 'unknown' | 'syncing' | 'ready' | 'error', required
    - `mta_sts` 'unknown' | 'syncing' | 'ready' | 'error', required
  - `managed_dns_status_since` object, required: When each managed record last entered the "syncing" status. For dmarc, falls back to dmarc_setup_at when the transition predates tracking; other records are null when they have never synced or the transition predates tracking. Useful for estimating how long a "syncing" record has been waiting on DNS propagation.
    - `dmarc` string, date-time, nullable, required
    - `spf` string, date-time, nullable, required
    - `dkim` string, date-time, nullable, required
    - `bimi` string, date-time, nullable, required
    - `mta_sts` string, date-time, nullable, required
  - `monitoring_status` 'drifted' | 'none' | 'pending' | 'setup' | 'failed', required
  - `monitoring_failure_reason` 'nameservers_unresolvable' | 'dmarc_record_missing' | 'dmarc_record_added_as_txt_not_cname' | 'dmarc_record_on_parent_only' | 'dmarc_record_missing_palisade_rua' | 'dmarc_record_invalid' | 'dmarc_multiple_records', nullable, required
  - `monitoring_failure_detail` DmarcSetupFailureDetail, nullable, required
    - `observed` string
    - `expected_rua` string
    - `from_hostname` string
    - `record_count` number
  - `monitoring_email` string, required
  - `open_tasks_count` number, required: Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and `expand[]=tasks` leaves them out to match.
  - `highest_open_task_priority` integer, nullable, required: Priority of the most urgent open task on this domain, on the same inverted scale as a task's own priority: 0 critical, 1 high, 2 medium, 3 low. Null when the domain has no open tasks. Sort on "severity" to order domains by it.
  - `score` number, required
  - `score_band` 'critical' | 'bad' | 'good' | 'great', required: Risk band the score falls in: critical, bad, good, or great. The same banding the dashboard shows, so clients do not have to reimplement the thresholds.
  - `is_parked` boolean, required
  - `is_dmarc_managed` boolean, required
  - `is_spf_managed` boolean, required
  - `is_dkim_managed` boolean, required
  - `is_bimi_managed` boolean, required
  - `is_mta_sts_managed` boolean, required
  - `bimi_options` object, required
    - `enabled` boolean, required
    - `logo` string, uri, nullable, required
    - `certificate` string, uri, nullable, required
  - `bimi_error_reason` 'setup_timeout' | 'drift' | 'certificate_invalid' | 'record_conflict' | 'delegation_missing' | 'publish_failed' | 'dkim_key_error' | 'check_failed', nullable, required: Why managed_dns_status.bimi is "error". "setup_timeout" means the customer CNAME was never detected within the verification window (setup was never completed); "drift" means a previously verified CNAME stopped pointing at Palisade; "record_conflict" means default._bimi holds conflicting records — see dns_conflicts. Null when there is no error or the error predates reason tracking.
  - `dmarc_error_reason` 'setup_timeout' | 'drift' | 'certificate_invalid' | 'record_conflict' | 'delegation_missing' | 'publish_failed' | 'dkim_key_error' | 'check_failed', nullable, required: Why managed_dns_status.dmarc is "error". "record_conflict" means _dmarc holds records that conflict with each other — a CNAME coexisting with other data, or more than one DMARC record — and the domain's DMARC policy is not reliably enforced. See dns_conflicts for the offending records. Null when there is no error or the error predates reason tracking.
  - `spf_error_reason` 'setup_timeout' | 'drift' | 'certificate_invalid' | 'record_conflict' | 'delegation_missing' | 'publish_failed' | 'dkim_key_error' | 'check_failed', nullable, required: Why managed_dns_status.spf is "error". See dmarc_error_reason for the meaning of each value.
  - `dkim_error_reason` 'setup_timeout' | 'drift' | 'certificate_invalid' | 'record_conflict' | 'delegation_missing' | 'publish_failed' | 'dkim_key_error' | 'check_failed', nullable, required: Why managed_dns_status.dkim is "error". See dmarc_error_reason for the meaning of each value.
  - `mta_sts_error_reason` 'setup_timeout' | 'drift' | 'certificate_invalid' | 'record_conflict' | 'delegation_missing' | 'publish_failed' | 'dkim_key_error' | 'check_failed', nullable, required: Why managed_dns_status.mta_sts is "error". See dmarc_error_reason for the meaning of each value.
  - `dns_conflicts` DnsConflict[], required: Unresolved record conflicts observed at labels Palisade manages or monitors for this domain. Empty for a healthy domain. Each entry quotes the offending records verbatim along with what every authoritative nameserver and public resolver returned, so it can be acted on without a second investigation.
    - `label` string, required: The exact DNS name the conflicting records sit at.
    - `protocol` 'dmarc' | 'spf' | 'bimi' | 'mta_sts' | 'dkim', required
    - `kind` 'cname_with_other_data' | 'multiple_dmarc_records' | 'multiple_spf_records' | 'multiple_bimi_records' | 'cname_target_unresolvable' | 'cname_chain_too_deep' | 'authoritative_disagreement' | 'resolver_divergence' | 'managed_delegation_missing', required
    - `summary` string, required
    - `rfc` string, required: The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".
    - `consequence` string, required: What this actually does to mail for this domain, in plain language.
    - `remediation` string, required: Which record to delete and which to keep, stated concretely enough to act on.
    - `conflicting_records` string[], required: The offending record values, verbatim as published.
    - `authoritative_nameservers` object[], required: Every authoritative nameserver queried and exactly what it returned.
      - `nameserver` string, required
      - `ip` string, required
      - `cname` string[], required
      - `txt` string[], required
      - `answered` boolean, required
      - `timed_out` boolean, required
    - `public_resolvers` object[], required: Independent public resolvers queried and exactly what each returned.
      - `resolver` string, required
      - `ip` string, required
      - `cname` string[], required
      - `txt` string[], required
      - `answered` boolean, required
      - `timed_out` boolean, required
    - `occurrence_count` number, required: How many detection runs have observed this conflict.
    - `first_detected_at` string, date-time, required
    - `last_detected_at` string, date-time, required
  - `bimi_cname_target` string, required: The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.
  - `bimi_txt_value` string, nullable, required: The fully-formed BIMI TXT value, populated whenever bimi_options.logo is set (via asset ingestion or a direct bimi_options update). The a= tag is included only when a certificate URL is also set. Customers who prefer not to delegate via CNAME can publish this value at default._bimi.{domain} themselves.
  - `target_spf` string, nullable, required
  - `last_14_days_volume` number, required
  - `last_14_days_dmarc_pass_pct` number, required
  - `last_14_days_spf_pass_pct` number, required
  - `last_14_days_dkim_pass_pct` number, required
  - `group_id` string, uuid, nullable, required
  - `registrar` string, nullable, required
  - `dmarc_setup_at` string, date-time, nullable, required
  - `dmarc_verified_at` string, date-time, nullable, required: When the domain first reached the "setup" monitoring status and DMARC report collection began.
  - `monitoring_since` string, nullable, required: The first day (yyyy-MM-dd) a DMARC aggregate report was actually received for this domain. The honest denominator for any activity claim: nothing before this day was observable, so a domain monitored for a week can never truthfully read as quiet for ninety days. Null until the first report arrives.
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `409`: Conflict

---

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