Palisade API

Version 2025-04-30 · OpenAPI JSON · Guide

The Palisade API uses independent rate-limit buckets. Honor the response headers — do not hard-code limits.

Buckets
Headers on every response
Headers on 429 responses
429 response body

{ "error": "rate_limit_exceeded", "scope": "global" | "dns" | "api_key" | "api_key_dns" | "signup" | "mcp_oauth", "limit": N, "window_seconds": N, "retry_after_seconds": N, "message": "..." }. Clients must respect Retry-After and back off exponentially on repeat failures.

Keying

Limits are applied per API key when the request carries Basic credentials, per JWT subject for dashboard-session callers, and fall back to per source IP otherwise. Multiple keys from the same host each get their own bucket.

Authentication

Authenticated endpoints accept either scheme below. API-key clients must also send the Palisade-Version header on every request.

BearerAuthHTTP bearer (JWT)
BasicAuthHTTP Basic (API key)

API key sent as HTTP Basic credentials. Put the API key in the username and leave the password empty: Authorization: Basic base64(<api_key>:).

Health Check

Check API availability

GET/health-check

Example request

curl "https://api.palisade.email/health-check"

Responses

200object

Success

Response body
messagestringrequired
successbooleanrequired

Domain

List domains

GET/domainsrequires auth

Query parameters

urlstring
groupstring (uuid)
ungroupedstring enum
One of: true, false
dmarc_policiesarray of DmarcPolicy
One of: none, quarantine, reject
monitoring_statusesarray of DmarcSetupState
One of: drifted, none, pending, setup, failed
is_parkedstring enum
One of: true, false
scoreobject
sortstring enum

"severity" orders by ticket priority, then count, with no-ticket domains last under desc and first under asc. "status" keeps configured domains (including zero tickets) before monitoring/setup states in both directions, and applies severity ordering within each group.

One of: created_at, url, monitoring_status, dmarc_policy, score, last_14_days_volume, last_14_days_dmarc_pass_pct, last_14_days_spf_pass_pct, last_14_days_dkim_pass_pct, open_tasks_count, severity, status, group
sort_directionstring enum
One of: desc, asc
per_pagenumber
pagenumber
expandarray of string enum
One of: group, tasks

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of Domainrequired
Domain
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
dmarc_optionsobjectrequired
properties
additional_emailsarray of string (email)required
legacy_ruf_emailsarray of string (email)
policyDmarcPolicyrequired
One of: none, quarantine, reject
pctnumberrequired
Min: 0 · Max: 100
spstring enumrequired
One of: none, quarantine, reject, same
strict_spfbooleanrequired
strict_dkimbooleanrequired
spf_optionsobjectrequired
properties
force_flatteningbooleanrequired
enabledbooleanrequired
mechanism_descriptionsobject
managed_dns_statusobjectrequired
properties
dmarcDnsStatusrequired
One of: unknown, syncing, ready, error
spfDnsStatusrequired
One of: unknown, syncing, ready, error
dkimDnsStatusrequired
One of: unknown, syncing, ready, error
bimiDnsStatusrequired
One of: unknown, syncing, ready, error
mta_stsDnsStatusrequired
One of: unknown, syncing, ready, error
managed_dns_status_sinceobjectrequired

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.

properties
dmarcstring (date-time), nullablerequired
spfstring (date-time), nullablerequired
dkimstring (date-time), nullablerequired
bimistring (date-time), nullablerequired
mta_stsstring (date-time), nullablerequired
monitoring_statusDmarcSetupStaterequired
One of: drifted, none, pending, setup, failed
monitoring_failure_reasonDmarcSetupFailureReasonrequired
One of: 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
monitoring_failure_detailDmarcSetupFailureDetailrequired
DmarcSetupFailureDetail
observedstring
expected_ruastring
from_hostnamestring
record_countnumber
monitoring_emailstringrequired
open_tasks_countnumberrequired

Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and expand[]=tasks leaves them out to match.

Min: 0
highest_open_task_priorityinteger, nullablerequired

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.

Min: 0 · Max: 3
scorenumberrequired
Min: 0 · Max: 100
score_bandstring enumrequired

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.

One of: critical, bad, good, great
is_parkedbooleanrequired
is_dmarc_managedbooleanrequired
is_spf_managedbooleanrequired
is_dkim_managedbooleanrequired
is_bimi_managedbooleanrequired
is_mta_sts_managedbooleanrequired
bimi_optionsobjectrequired
properties
enabledbooleanrequired
logostring (uri), nullablerequired
certificatestring (uri), nullablerequired
bimi_error_reasonManagedDnsErrorReasonrequired

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.

One of: setup_timeout, drift, certificate_invalid, record_conflict, delegation_missing, publish_failed, dkim_key_error, check_failed
dmarc_error_reasonManagedDnsErrorReason & objectrequired

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.

spf_error_reasonManagedDnsErrorReason & objectrequired

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.

dkim_error_reasonManagedDnsErrorReason & objectrequired

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.

mta_sts_error_reasonManagedDnsErrorReason & objectrequired

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.

dns_conflictsarray of DnsConflictrequired

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.

DnsConflict
labelstringrequired

The exact DNS name the conflicting records sit at.

protocolDnsConflictProtocolrequired
One of: dmarc, spf, bimi, mta_sts, dkim
kindDnsConflictKindrequired
One of: 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
summarystringrequired
rfcstringrequired

The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".

consequencestringrequired

What this actually does to mail for this domain, in plain language.

remediationstringrequired

Which record to delete and which to keep, stated concretely enough to act on.

conflicting_recordsarray of stringrequired

The offending record values, verbatim as published.

authoritative_nameserversarray of objectrequired

Every authoritative nameserver queried and exactly what it returned.

items
nameserverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
public_resolversarray of objectrequired

Independent public resolvers queried and exactly what each returned.

items
resolverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
occurrence_countnumberrequired

How many detection runs have observed this conflict.

first_detected_atstring (date-time)required
last_detected_atstring (date-time)required
bimi_cname_targetstringrequired

The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.

bimi_txt_valuestring, nullablerequired

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_spfstring, nullablerequired
last_14_days_volumenumberrequired
Min: 0
last_14_days_dmarc_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_spf_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_dkim_pass_pctnumberrequired
Min: 0 · Max: 100
group_idstring (uuid), nullablerequired
registrarstring, nullablerequired
groupGroup
Group
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
domainsobject
properties
countnumberrequired
enforcement_pctnumberrequired
last_14_days_volumenumberrequired
last_14_days_dmarc_pass_pctnumberrequired
average_scorenumberrequired
created_atstring (date-time)required
updated_atstring (date-time)required
tasksarray of Task

Returns only tasks with status "open"

Task
idstring (uuid)required
domain_idstring (uuid)required
domainobject
properties
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
scorenumberrequired

The domain audit score as it stands now.

Min: 0 · Max: 100
score_gaininteger

How much of the domain score completing this ticket wins back, by the same scoring the domain overview shows. 0 for ticket types the score does not measure. Present only with expand[]=domain, since it depends on the domain as it stands now.

Min: 0
sending_domainstring, nullablerequired
source_idstring (uuid), nullablerequired
sourceobject
properties
idstring (uuid)required
namestringrequired
homepagestring (uri), nullablerequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
dkim_discovery_selectorsarray of stringrequired
instructionsobject, nullable

BETA: Only expandable for GET /tasks/:id. Can contain instructions sometimes.

properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
source_aliasstring, nullablerequired
prioritynumberrequired
sequencenumberrequired

Where the task sits in the email-authentication rollout, lower first: 10 DMARC setup, 20 foundation records, 30 SPF/DKIM alignment, 40 cleanup, 50 enforcement, 60 hardening. Separate from priority, which is urgency; sequence orders tasks of equal priority, since an alignment task cannot be worked before DMARC reporting exists to show the failure.

statusTaskStatusrequired
One of: open, snoozed, canceled, dismissed, pending, done
typeTaskTyperequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
descriptionstringrequired
snoozed_untilstring (date-time), nullablerequired
marked_pending_atstring (date-time), nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
resolution_reasonTaskResolutionReasonrequired

Why a done ticket closed. 'verified': Palisade's own check found the problem gone. 'manual': a person or an API caller marked it done and nothing was checked. Null on a ticket that is not done, and on one closed before the reason was first recorded. More values may be added, so treat an unknown one as unspecified.

One of: verified, manual
dmarc_setup_atstring (date-time), nullablerequired
dmarc_verified_atstring (date-time), nullablerequired

When the domain first reached the "setup" monitoring status and DMARC report collection began.

monitoring_sincestring, nullablerequired

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_atstring (date-time)required
updated_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Add a domain

POST/domainsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

urlstringrequired
group_idstring (uuid)
use_stored_scanboolean

Example request

curl -X POST "https://api.palisade.email/domains" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "string",
  "group_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1",
  "use_stored_scan": true
}'

Responses

200object

Success

Response body
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
dmarc_optionsobjectrequired
properties
additional_emailsarray of string (email)required
legacy_ruf_emailsarray of string (email)
policyDmarcPolicyrequired
One of: none, quarantine, reject
pctnumberrequired
Min: 0 · Max: 100
spstring enumrequired
One of: none, quarantine, reject, same
strict_spfbooleanrequired
strict_dkimbooleanrequired
spf_optionsobjectrequired
properties
force_flatteningbooleanrequired
enabledbooleanrequired
mechanism_descriptionsobject
managed_dns_statusobjectrequired
properties
dmarcDnsStatusrequired
One of: unknown, syncing, ready, error
spfDnsStatusrequired
One of: unknown, syncing, ready, error
dkimDnsStatusrequired
One of: unknown, syncing, ready, error
bimiDnsStatusrequired
One of: unknown, syncing, ready, error
mta_stsDnsStatusrequired
One of: unknown, syncing, ready, error
managed_dns_status_sinceobjectrequired

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.

properties
dmarcstring (date-time), nullablerequired
spfstring (date-time), nullablerequired
dkimstring (date-time), nullablerequired
bimistring (date-time), nullablerequired
mta_stsstring (date-time), nullablerequired
monitoring_statusDmarcSetupStaterequired
One of: drifted, none, pending, setup, failed
monitoring_failure_reasonDmarcSetupFailureReasonrequired
One of: 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
monitoring_failure_detailDmarcSetupFailureDetailrequired
DmarcSetupFailureDetail
observedstring
expected_ruastring
from_hostnamestring
record_countnumber
monitoring_emailstringrequired
open_tasks_countnumberrequired

Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and expand[]=tasks leaves them out to match.

Min: 0
highest_open_task_priorityinteger, nullablerequired

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.

Min: 0 · Max: 3
scorenumberrequired
Min: 0 · Max: 100
score_bandstring enumrequired

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.

One of: critical, bad, good, great
is_parkedbooleanrequired
is_dmarc_managedbooleanrequired
is_spf_managedbooleanrequired
is_dkim_managedbooleanrequired
is_bimi_managedbooleanrequired
is_mta_sts_managedbooleanrequired
bimi_optionsobjectrequired
properties
enabledbooleanrequired
logostring (uri), nullablerequired
certificatestring (uri), nullablerequired
bimi_error_reasonManagedDnsErrorReasonrequired

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.

One of: setup_timeout, drift, certificate_invalid, record_conflict, delegation_missing, publish_failed, dkim_key_error, check_failed
dmarc_error_reasonManagedDnsErrorReason & objectrequired

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.

spf_error_reasonManagedDnsErrorReason & objectrequired

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.

dkim_error_reasonManagedDnsErrorReason & objectrequired

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.

mta_sts_error_reasonManagedDnsErrorReason & objectrequired

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.

dns_conflictsarray of DnsConflictrequired

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.

DnsConflict
labelstringrequired

The exact DNS name the conflicting records sit at.

protocolDnsConflictProtocolrequired
One of: dmarc, spf, bimi, mta_sts, dkim
kindDnsConflictKindrequired
One of: 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
summarystringrequired
rfcstringrequired

The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".

consequencestringrequired

What this actually does to mail for this domain, in plain language.

remediationstringrequired

Which record to delete and which to keep, stated concretely enough to act on.

conflicting_recordsarray of stringrequired

The offending record values, verbatim as published.

authoritative_nameserversarray of objectrequired

Every authoritative nameserver queried and exactly what it returned.

items
nameserverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
public_resolversarray of objectrequired

Independent public resolvers queried and exactly what each returned.

items
resolverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
occurrence_countnumberrequired

How many detection runs have observed this conflict.

first_detected_atstring (date-time)required
last_detected_atstring (date-time)required
bimi_cname_targetstringrequired

The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.

bimi_txt_valuestring, nullablerequired

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_spfstring, nullablerequired
last_14_days_volumenumberrequired
Min: 0
last_14_days_dmarc_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_spf_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_dkim_pass_pctnumberrequired
Min: 0 · Max: 100
group_idstring (uuid), nullablerequired
registrarstring, nullablerequired
dmarc_setup_atstring (date-time), nullablerequired
dmarc_verified_atstring (date-time), nullablerequired

When the domain first reached the "setup" monitoring status and DMARC report collection began.

monitoring_sincestring, nullablerequired

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_atstring (date-time)required
updated_atstring (date-time)required
409object

Conflict

Response body

Get a domain

GET/domains/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200Domain

Success

Response body
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
dmarc_optionsobjectrequired
properties
additional_emailsarray of string (email)required
legacy_ruf_emailsarray of string (email)
policyDmarcPolicyrequired
One of: none, quarantine, reject
pctnumberrequired
Min: 0 · Max: 100
spstring enumrequired
One of: none, quarantine, reject, same
strict_spfbooleanrequired
strict_dkimbooleanrequired
spf_optionsobjectrequired
properties
force_flatteningbooleanrequired
enabledbooleanrequired
mechanism_descriptionsobject
managed_dns_statusobjectrequired
properties
dmarcDnsStatusrequired
One of: unknown, syncing, ready, error
spfDnsStatusrequired
One of: unknown, syncing, ready, error
dkimDnsStatusrequired
One of: unknown, syncing, ready, error
bimiDnsStatusrequired
One of: unknown, syncing, ready, error
mta_stsDnsStatusrequired
One of: unknown, syncing, ready, error
managed_dns_status_sinceobjectrequired

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.

properties
dmarcstring (date-time), nullablerequired
spfstring (date-time), nullablerequired
dkimstring (date-time), nullablerequired
bimistring (date-time), nullablerequired
mta_stsstring (date-time), nullablerequired
monitoring_statusDmarcSetupStaterequired
One of: drifted, none, pending, setup, failed
monitoring_failure_reasonDmarcSetupFailureReasonrequired
One of: 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
monitoring_failure_detailDmarcSetupFailureDetailrequired
DmarcSetupFailureDetail
observedstring
expected_ruastring
from_hostnamestring
record_countnumber
monitoring_emailstringrequired
open_tasks_countnumberrequired

Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and expand[]=tasks leaves them out to match.

Min: 0
highest_open_task_priorityinteger, nullablerequired

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.

Min: 0 · Max: 3
scorenumberrequired
Min: 0 · Max: 100
score_bandstring enumrequired

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.

One of: critical, bad, good, great
is_parkedbooleanrequired
is_dmarc_managedbooleanrequired
is_spf_managedbooleanrequired
is_dkim_managedbooleanrequired
is_bimi_managedbooleanrequired
is_mta_sts_managedbooleanrequired
bimi_optionsobjectrequired
properties
enabledbooleanrequired
logostring (uri), nullablerequired
certificatestring (uri), nullablerequired
bimi_error_reasonManagedDnsErrorReasonrequired

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.

One of: setup_timeout, drift, certificate_invalid, record_conflict, delegation_missing, publish_failed, dkim_key_error, check_failed
dmarc_error_reasonManagedDnsErrorReason & objectrequired

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.

spf_error_reasonManagedDnsErrorReason & objectrequired

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.

dkim_error_reasonManagedDnsErrorReason & objectrequired

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.

mta_sts_error_reasonManagedDnsErrorReason & objectrequired

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.

dns_conflictsarray of DnsConflictrequired

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.

DnsConflict
labelstringrequired

The exact DNS name the conflicting records sit at.

protocolDnsConflictProtocolrequired
One of: dmarc, spf, bimi, mta_sts, dkim
kindDnsConflictKindrequired
One of: 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
summarystringrequired
rfcstringrequired

The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".

consequencestringrequired

What this actually does to mail for this domain, in plain language.

remediationstringrequired

Which record to delete and which to keep, stated concretely enough to act on.

conflicting_recordsarray of stringrequired

The offending record values, verbatim as published.

authoritative_nameserversarray of objectrequired

Every authoritative nameserver queried and exactly what it returned.

items
nameserverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
public_resolversarray of objectrequired

Independent public resolvers queried and exactly what each returned.

items
resolverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
occurrence_countnumberrequired

How many detection runs have observed this conflict.

first_detected_atstring (date-time)required
last_detected_atstring (date-time)required
bimi_cname_targetstringrequired

The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.

bimi_txt_valuestring, nullablerequired

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_spfstring, nullablerequired
last_14_days_volumenumberrequired
Min: 0
last_14_days_dmarc_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_spf_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_dkim_pass_pctnumberrequired
Min: 0 · Max: 100
group_idstring (uuid), nullablerequired
registrarstring, nullablerequired
groupGroup
Group
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
domainsobject
properties
countnumberrequired
enforcement_pctnumberrequired
last_14_days_volumenumberrequired
last_14_days_dmarc_pass_pctnumberrequired
average_scorenumberrequired
created_atstring (date-time)required
updated_atstring (date-time)required
tasksarray of Task

Returns only tasks with status "open"

Task
idstring (uuid)required
domain_idstring (uuid)required
domainobject
properties
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
scorenumberrequired

The domain audit score as it stands now.

Min: 0 · Max: 100
score_gaininteger

How much of the domain score completing this ticket wins back, by the same scoring the domain overview shows. 0 for ticket types the score does not measure. Present only with expand[]=domain, since it depends on the domain as it stands now.

Min: 0
sending_domainstring, nullablerequired
source_idstring (uuid), nullablerequired
sourceobject
properties
idstring (uuid)required
namestringrequired
homepagestring (uri), nullablerequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
valuestring
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
dkim_discovery_selectorsarray of stringrequired
instructionsobject, nullable

BETA: Only expandable for GET /tasks/:id. Can contain instructions sometimes.

properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
source_aliasstring, nullablerequired
prioritynumberrequired
sequencenumberrequired

Where the task sits in the email-authentication rollout, lower first: 10 DMARC setup, 20 foundation records, 30 SPF/DKIM alignment, 40 cleanup, 50 enforcement, 60 hardening. Separate from priority, which is urgency; sequence orders tasks of equal priority, since an alignment task cannot be worked before DMARC reporting exists to show the failure.

statusTaskStatusrequired
One of: open, snoozed, canceled, dismissed, pending, done
typeTaskTyperequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
descriptionstringrequired
snoozed_untilstring (date-time), nullablerequired
marked_pending_atstring (date-time), nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
resolution_reasonTaskResolutionReasonrequired

Why a done ticket closed. 'verified': Palisade's own check found the problem gone. 'manual': a person or an API caller marked it done and nothing was checked. Null on a ticket that is not done, and on one closed before the reason was first recorded. More values may be added, so treat an unknown one as unspecified.

One of: verified, manual
dmarc_setup_atstring (date-time), nullablerequired
dmarc_verified_atstring (date-time), nullablerequired

When the domain first reached the "setup" monitoring status and DMARC report collection began.

monitoring_sincestring, nullablerequired

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_atstring (date-time)required
updated_atstring (date-time)required

Update a domain

POST/domains/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

group_idstring (uuid), nullable
is_parkedboolean
dmarc_optionsobject
properties
additional_emailsarray of string (email)
legacy_ruf_emailsarray of string (email)
policyDmarcPolicy
One of: none, quarantine, reject
pctnumber
Min: 0 · Max: 100
spstring enum
One of: none, quarantine, reject, same
strict_spfboolean
strict_dkimboolean
spf_optionsobject
properties
force_flatteningboolean
enabledboolean
mechanism_descriptionsobject
dmarc_setup_atstring (date-time)
target_spfstring
bimi_optionsobject
properties
enabledboolean
logostring (uri), nullable
certificatestring (uri), nullable
backfill_ticketsboolean

Example request

curl -X POST "https://api.palisade.email/domains/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "group_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1",
  "is_parked": true,
  "dmarc_options": {
    "additional_emails": [
      "user@example.com"
    ],
    "legacy_ruf_emails": [
      "user@example.com"
    ],
    "policy": "none",
    "pct": 0,
    "sp": "none",
    "strict_spf": true,
    "strict_dkim": true
  },
  "spf_options": {
    "force_flattening": true,
    "enabled": true,
    "mechanism_descriptions": {}
  },
  "dmarc_setup_at": "2025-01-15T12:00:00.000Z",
  "target_spf": "string",
  "bimi_options": {
    "enabled": true,
    "logo": "https://example.com",
    "certificate": "https://example.com"
  },
  "backfill_tickets": true
}'

Responses

200object

Success

Response body
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
dmarc_optionsobjectrequired
properties
additional_emailsarray of string (email)required
legacy_ruf_emailsarray of string (email)
policyDmarcPolicyrequired
One of: none, quarantine, reject
pctnumberrequired
Min: 0 · Max: 100
spstring enumrequired
One of: none, quarantine, reject, same
strict_spfbooleanrequired
strict_dkimbooleanrequired
spf_optionsobjectrequired
properties
force_flatteningbooleanrequired
enabledbooleanrequired
mechanism_descriptionsobject
managed_dns_statusobjectrequired
properties
dmarcDnsStatusrequired
One of: unknown, syncing, ready, error
spfDnsStatusrequired
One of: unknown, syncing, ready, error
dkimDnsStatusrequired
One of: unknown, syncing, ready, error
bimiDnsStatusrequired
One of: unknown, syncing, ready, error
mta_stsDnsStatusrequired
One of: unknown, syncing, ready, error
managed_dns_status_sinceobjectrequired

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.

properties
dmarcstring (date-time), nullablerequired
spfstring (date-time), nullablerequired
dkimstring (date-time), nullablerequired
bimistring (date-time), nullablerequired
mta_stsstring (date-time), nullablerequired
monitoring_statusDmarcSetupStaterequired
One of: drifted, none, pending, setup, failed
monitoring_failure_reasonDmarcSetupFailureReasonrequired
One of: 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
monitoring_failure_detailDmarcSetupFailureDetailrequired
DmarcSetupFailureDetail
observedstring
expected_ruastring
from_hostnamestring
record_countnumber
monitoring_emailstringrequired
open_tasks_countnumberrequired

Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and expand[]=tasks leaves them out to match.

Min: 0
highest_open_task_priorityinteger, nullablerequired

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.

Min: 0 · Max: 3
scorenumberrequired
Min: 0 · Max: 100
score_bandstring enumrequired

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.

One of: critical, bad, good, great
is_parkedbooleanrequired
is_dmarc_managedbooleanrequired
is_spf_managedbooleanrequired
is_dkim_managedbooleanrequired
is_bimi_managedbooleanrequired
is_mta_sts_managedbooleanrequired
bimi_optionsobjectrequired
properties
enabledbooleanrequired
logostring (uri), nullablerequired
certificatestring (uri), nullablerequired
bimi_error_reasonManagedDnsErrorReasonrequired

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.

One of: setup_timeout, drift, certificate_invalid, record_conflict, delegation_missing, publish_failed, dkim_key_error, check_failed
dmarc_error_reasonManagedDnsErrorReason & objectrequired

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.

spf_error_reasonManagedDnsErrorReason & objectrequired

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.

dkim_error_reasonManagedDnsErrorReason & objectrequired

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.

mta_sts_error_reasonManagedDnsErrorReason & objectrequired

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.

dns_conflictsarray of DnsConflictrequired

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.

DnsConflict
labelstringrequired

The exact DNS name the conflicting records sit at.

protocolDnsConflictProtocolrequired
One of: dmarc, spf, bimi, mta_sts, dkim
kindDnsConflictKindrequired
One of: 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
summarystringrequired
rfcstringrequired

The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".

consequencestringrequired

What this actually does to mail for this domain, in plain language.

remediationstringrequired

Which record to delete and which to keep, stated concretely enough to act on.

conflicting_recordsarray of stringrequired

The offending record values, verbatim as published.

authoritative_nameserversarray of objectrequired

Every authoritative nameserver queried and exactly what it returned.

items
nameserverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
public_resolversarray of objectrequired

Independent public resolvers queried and exactly what each returned.

items
resolverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
occurrence_countnumberrequired

How many detection runs have observed this conflict.

first_detected_atstring (date-time)required
last_detected_atstring (date-time)required
bimi_cname_targetstringrequired

The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.

bimi_txt_valuestring, nullablerequired

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_spfstring, nullablerequired
last_14_days_volumenumberrequired
Min: 0
last_14_days_dmarc_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_spf_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_dkim_pass_pctnumberrequired
Min: 0 · Max: 100
group_idstring (uuid), nullablerequired
registrarstring, nullablerequired
dmarc_setup_atstring (date-time), nullablerequired
dmarc_verified_atstring (date-time), nullablerequired

When the domain first reached the "setup" monitoring status and DMARC report collection began.

monitoring_sincestring, nullablerequired

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_atstring (date-time)required
updated_atstring (date-time)required

Delete a domain

DELETE/domains/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/domains/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Deleted

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

Add domains in bulk

POST/domains/bulkrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

domainsarray of objectrequired
items
urlstringrequired
group_idstring (uuid)

Example request

curl -X POST "https://api.palisade.email/domains/bulk" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "domains": [
    {
      "url": "string",
      "group_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
    }
  ]
}'

Responses

200object

Success

Response body
creatednumberrequired

How many domains were created.

failednumberrequired

How many entries could not be created.

resultsarray of objectrequired

One entry per submitted domain, in request order. Entries are independent: a failure here does not roll back the domains that succeeded, and the response is 200 even when every entry failed, so inspect "failed" rather than the status code.

items
urlstringrequired

The domain from the request, echoed in the order it was sent.

statusstring enumrequired
One of: created, failed
domainobject, nullablerequired

The created domain, or null when this entry failed.

properties
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
dmarc_optionsobjectrequired
properties
additional_emailsarray of string (email)required
legacy_ruf_emailsarray of string (email)
policyDmarcPolicyrequired
One of: none, quarantine, reject
pctnumberrequired
Min: 0 · Max: 100
spstring enumrequired
One of: none, quarantine, reject, same
strict_spfbooleanrequired
strict_dkimbooleanrequired
spf_optionsobjectrequired
properties
force_flatteningbooleanrequired
enabledbooleanrequired
mechanism_descriptionsobject
managed_dns_statusobjectrequired
properties
dmarcDnsStatusrequired
One of: unknown, syncing, ready, error
spfDnsStatusrequired
One of: unknown, syncing, ready, error
dkimDnsStatusrequired
One of: unknown, syncing, ready, error
bimiDnsStatusrequired
One of: unknown, syncing, ready, error
mta_stsDnsStatusrequired
One of: unknown, syncing, ready, error
managed_dns_status_sinceobjectrequired

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.

properties
dmarcstring (date-time), nullablerequired
spfstring (date-time), nullablerequired
dkimstring (date-time), nullablerequired
bimistring (date-time), nullablerequired
mta_stsstring (date-time), nullablerequired
monitoring_statusDmarcSetupStaterequired
One of: drifted, none, pending, setup, failed
monitoring_failure_reasonDmarcSetupFailureReasonrequired
One of: 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
monitoring_failure_detailDmarcSetupFailureDetailrequired
DmarcSetupFailureDetail
observedstring
expected_ruastring
from_hostnamestring
record_countnumber
monitoring_emailstringrequired
open_tasks_countnumberrequired

Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and expand[]=tasks leaves them out to match.

Min: 0
highest_open_task_priorityinteger, nullablerequired

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.

Min: 0 · Max: 3
scorenumberrequired
Min: 0 · Max: 100
score_bandstring enumrequired

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.

One of: critical, bad, good, great
is_parkedbooleanrequired
is_dmarc_managedbooleanrequired
is_spf_managedbooleanrequired
is_dkim_managedbooleanrequired
is_bimi_managedbooleanrequired
is_mta_sts_managedbooleanrequired
bimi_optionsobjectrequired
properties
enabledbooleanrequired
logostring (uri), nullablerequired
certificatestring (uri), nullablerequired
bimi_error_reasonManagedDnsErrorReasonrequired

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.

One of: setup_timeout, drift, certificate_invalid, record_conflict, delegation_missing, publish_failed, dkim_key_error, check_failed
dmarc_error_reasonManagedDnsErrorReason & objectrequired

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.

spf_error_reasonManagedDnsErrorReason & objectrequired

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.

dkim_error_reasonManagedDnsErrorReason & objectrequired

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.

mta_sts_error_reasonManagedDnsErrorReason & objectrequired

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.

dns_conflictsarray of DnsConflictrequired

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.

DnsConflict
labelstringrequired

The exact DNS name the conflicting records sit at.

protocolDnsConflictProtocolrequired
One of: dmarc, spf, bimi, mta_sts, dkim
kindDnsConflictKindrequired
One of: 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
summarystringrequired
rfcstringrequired

The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".

consequencestringrequired

What this actually does to mail for this domain, in plain language.

remediationstringrequired

Which record to delete and which to keep, stated concretely enough to act on.

conflicting_recordsarray of stringrequired

The offending record values, verbatim as published.

authoritative_nameserversarray of objectrequired

Every authoritative nameserver queried and exactly what it returned.

items
nameserverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
public_resolversarray of objectrequired

Independent public resolvers queried and exactly what each returned.

items
resolverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
occurrence_countnumberrequired

How many detection runs have observed this conflict.

first_detected_atstring (date-time)required
last_detected_atstring (date-time)required
bimi_cname_targetstringrequired

The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.

bimi_txt_valuestring, nullablerequired

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_spfstring, nullablerequired
last_14_days_volumenumberrequired
Min: 0
last_14_days_dmarc_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_spf_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_dkim_pass_pctnumberrequired
Min: 0 · Max: 100
group_idstring (uuid), nullablerequired
registrarstring, nullablerequired
dmarc_setup_atstring (date-time), nullablerequired
dmarc_verified_atstring (date-time), nullablerequired

When the domain first reached the "setup" monitoring status and DMARC report collection began.

monitoring_sincestring, nullablerequired

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_atstring (date-time)required
updated_atstring (date-time)required
errorobject, nullablerequired

Why this entry failed, or null when it succeeded.

properties
codestring, nullablerequired
messagestring, nullablerequired

Upload BIMI assets

POST/domains/{id}/bimi/assetsrequires auth

Ingests a Verified Mark Certificate (VMC), extracts and verifies the logotype SVG embedded in the certificate, and hosts the matched certificate + logo pair at per-domain asset URLs with a short content-derived version suffix ({domain}/bimi/logo-{v}.svg and {domain}/bimi/certchain-{v}.pem). Re-posting the same PEM returns the same URLs; a new PEM gets fresh URLs so caches never serve stale assets.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

certificate_pemstring

The VMC as a PEM string. Alternative to the multipart certificate file part.

Min length: 1
certificate_urlstring (uri)

An https URL to fetch the VMC PEM from. Alternative to the multipart certificate file part.

Example request

curl -X POST "https://api.palisade.email/domains/<id>/bimi/assets" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "certificate_pem": "string",
  "certificate_url": "https://example.com"
}'

Responses

200BimiAssetsResponse

Success

Response body
certificate_urlstring (uri)required
logo_urlstring (uri)required
logotype_verifiedbooleanrequired

The SVG hosted at logo_url was recovered from the certificate's logotype extension and matches the digest the certificate asserts. This covers the logo only — it says nothing about whether the certificate chain validates. Read chain_verified for that.

svg_profilestring enumrequired
One of: tiny-ps
chain_verifiedbooleanrequired

The hosted certificate chain was verified end to end: every signature checks out, no certificate in the path is expired, and the path terminates in a pinned BIMI trust anchor. Uploads that cannot reach this state are rejected, so a 200 response always carries true.

chain_lengthintegerrequired

How many certificates the hosted chain contains, counting the VMC leaf, intermediates and root.

Min: 0
chain_repairedbooleanrequired

True when the uploaded PEM was missing certificates and Palisade completed the chain (fetching the intermediate from the certificate's Authority Information Access endpoint and appending the pinned root) before hosting it. The hosted chain, not the uploaded one, is what certificate_url serves.

trust_anchorstringrequired

Common name of the pinned VMC root the hosted chain terminates in.

san_verifiedbooleanrequired

The leaf certificate's subjectAltName covers the domain the assets were attached to.

not_afterstring (date-time)required

When the VMC leaf expires. VMCs are one-year certificates, so this is worth tracking.

warningsarray of stringrequired

Non-fatal observations about the certificate. "vmc-mark-type-oid-missing" means the leaf does not carry the VMC mark-type OIDs under 1.3.6.1.4.1.53087, which is certificate-authority dependent and does not block hosting.

certobjectrequired
properties
serialstringrequired
not_afterstring (date-time)required
common_namestring, nullablerequired
422object

Certificate rejected

Response body
codestring enumrequired
One of: bimi_certificate_invalid
reasonstring enumrequired
One of: pem_parse_failed, not_a_vmc, logotype_missing, logo_hash_mismatch, svg_not_tiny_ps, incomplete_chain, chain_untrusted, chain_expired, chain_signature_invalid, certificate_not_yet_valid, san_mismatch, contains_private_key
messagestringrequired

Get DNS records

GET/domains/{id}/dns-recordsrequires auth

Returns the consolidated, server-computed list of DNS records to publish for this domain, covering every enabled Palisade-managed feature (DMARC, SPF, DKIM, MTA-STS, TLS-RPT, BIMI) with per-record verification status. Records that are not yet verified are compared against live DNS, so "action" reflects what is actually published and "already_published" identifies records that need no change. Also reports the detected DNS provider hosting the domain, resolved from its live NS records, so the records can be published with a matching DNS integration.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<id>/dns-records" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200DnsRecordsResponse

Success

Response body
recordsarray of DnsRecordrequired
DnsRecord
purposeDnsRecordPurposerequired
One of: dmarc, spf, dkim, mta_sts, mta_sts_policy, tls_rpt, bimi
typeDnsRecordTyperequired
One of: TXT, CNAME, NS
hoststringrequired

Fully qualified record name.

relative_hoststringrequired

Record name relative to the domain apex; "@" designates the apex itself.

valuestringrequired
ttlintegerrequired

Recommended TTL in seconds.

Min: 0
actionDnsRecordActionrequired

How to publish this record, derived from what is currently live in DNS. "create" means nothing serving this purpose exists at the host yet; "replace" means a record for this purpose already occupies the host and must be overwritten with this value; "delete" means the record must be removed. When already_published is true the record is already correct and "replace" would be a no-op, so use already_published to decide whether to act at all.

One of: create, replace, delete
requiredbooleanrequired

False for records that improve an enabled feature but are not needed for it to function.

statusDnsRecordStatusrequired
One of: pending, verifying, verified, drifted
already_publishedboolean, nullablerequired

True when live DNS already serves exactly this value, so the record can be skipped. False when it is missing or serving something else. Null when the live lookup could not be completed, in which case "action" falls back to a static, type-derived value and should be treated as a best-effort hint.

all_verifiedbooleanrequired

True when every required record has status "verified".

warningsarray of DnsRecordWarningrequired

Risks to resolve before publishing these records. Empty in the normal case. Read these before applying anything: publishing an enforcing DMARC policy on a domain with no working SPF or DKIM causes receivers to reject or quarantine its mail.

DnsRecordWarning
codestringrequired

Stable identifier for the warning, safe to branch on.

messagestringrequired

Human-readable explanation of the risk.

dns_providerDetectedDnsProviderrequired

Where the domain's DNS is hosted, so the records can be published with a matching DNS tool, connector, or provider API. This is the DNS host, which is often not the registrar reported in "registrar".

DetectedDnsProvider
idstring, nullablerequired

Identifier of the DNS provider hosting the domain, derived from its live NS records. Deliberately an open set: ids recognized today are cloudflare, route53, godaddy, azure, google, namecheap, digitalocean, vercel, dnsimple, gandi, ovh, name.com, porkbun, hetzner, linode, networksolutions, microsoft365, wix, squarespace, ionos, hostinger, siteground, bluehost, hostgator, dreamhost, dnsmadeeasy, akamai, rackspace, cloudns, comodo, easydns, encirca, webnames, whc, rebel, register.com, hover, namesilo, dynadot, spaceship, one.com, enom, wordpress.com, hurricane-electric, and more are added over time, so treat an unfamiliar id the same as null rather than rejecting the response. Null when the nameservers do not match a known provider, disagree with each other, or could not be resolved — in that case use "nameservers" to decide, and never assume a provider.

nameserversarray of stringrequired

The nameservers the domain is delegated to. Empty when the lookup failed or returned nothing.

Verify a domain

POST/domains/{id}/verifyrequires auth

Queues full domain monitoring and synchronously re-checks records that are still propagating. "results" reports the purposes confirmed during this pass using the same slugs as GET /domains/{id}/dns-records.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/domains/<id>/verify" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200VerifyDomainResponse

Success

Response body
queuedbooleanrequired
verifiedobjectrequired
resultsVerifyResultsrequired

Outcome of the synchronous verification pass, keyed by the same purpose slugs as GET /domains/{id}/dns-records. A purpose is present only when it was confirmed during this pass; absence means it was not confirmed (it may already be verified, or still propagating). tls_rpt and mta_sts_policy are not covered by the synchronous pass and never appear.

VerifyResults
dmarcboolean
spfboolean
dkimboolean
mta_stsboolean
bimiboolean

Verify SPF for a domain

POST/domains/{id}/verify/spfrequires auth

Queues SPF verification and synchronously re-checks records that are still propagating. "results" reports the purposes confirmed during this pass using the same slugs as GET /domains/{id}/dns-records.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/domains/<id>/verify/spf" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200VerifyDomainResponse

Success

Response body
queuedbooleanrequired
verifiedobjectrequired
resultsVerifyResultsrequired

Outcome of the synchronous verification pass, keyed by the same purpose slugs as GET /domains/{id}/dns-records. A purpose is present only when it was confirmed during this pass; absence means it was not confirmed (it may already be verified, or still propagating). tls_rpt and mta_sts_policy are not covered by the synchronous pass and never appear.

VerifyResults
dmarcboolean
spfboolean
dkimboolean
mta_stsboolean
bimiboolean

Verify DKIM for a domain

POST/domains/{id}/verify/dkimrequires auth

Queues DKIM verification and synchronously re-checks records that are still propagating. "results" reports the purposes confirmed during this pass using the same slugs as GET /domains/{id}/dns-records.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/domains/<id>/verify/dkim" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200VerifyDomainResponse

Success

Response body
queuedbooleanrequired
verifiedobjectrequired
resultsVerifyResultsrequired

Outcome of the synchronous verification pass, keyed by the same purpose slugs as GET /domains/{id}/dns-records. A purpose is present only when it was confirmed during this pass; absence means it was not confirmed (it may already be verified, or still propagating). tls_rpt and mta_sts_policy are not covered by the synchronous pass and never appear.

VerifyResults
dmarcboolean
spfboolean
dkimboolean
mta_stsboolean
bimiboolean

Enable hosted DMARC

POST/domains/{id}/hosted-dmarcrequires auth

Rebuilds the Palisade-hosted DMARC record from the domain's current policy, publishes it, and returns the CNAME to point _dmarc at. Call this before showing anyone the CNAME: the delegation target is otherwise whatever was written when the domain was created, so a domain whose owner tightened their own DMARC policy since then would be switched onto a weaker one. Nothing is written to the database unless the publish succeeds, so a failure is safe to retry, and calling it on a domain that is already hosted changes nothing and answers hosted_dmarc_active: true.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/domains/<id>/hosted-dmarc" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200EnableHostedDmarcResponse

Success

Response body
hosted_dmarc_activebooleanrequired

False until the hosted CNAME resolves in live DNS. Publish "record" and Palisade flips this to true on its own; true already on a domain that was hosted before the call.

recordDnsRecord & objectrequired

The CNAME to publish at _dmarc.<domain>, rebuilt from the domain's current DMARC policy. Delete any DMARC TXT record still sitting at the same host, which conflicts with it.

properties
purposeDnsRecordPurposerequired
One of: dmarc, spf, dkim, mta_sts, mta_sts_policy, tls_rpt, bimi
typeDnsRecordTyperequired
One of: TXT, CNAME, NS
hoststringrequired

Fully qualified record name.

relative_hoststringrequired

Record name relative to the domain apex; "@" designates the apex itself.

valuestringrequired
ttlintegerrequired

Recommended TTL in seconds.

Min: 0
actionDnsRecordActionrequired

How to publish this record, derived from what is currently live in DNS. "create" means nothing serving this purpose exists at the host yet; "replace" means a record for this purpose already occupies the host and must be overwritten with this value; "delete" means the record must be removed. When already_published is true the record is already correct and "replace" would be a no-op, so use already_published to decide whether to act at all.

One of: create, replace, delete
requiredbooleanrequired

False for records that improve an enabled feature but are not needed for it to function.

statusDnsRecordStatusrequired
One of: pending, verifying, verified, drifted
already_publishedboolean, nullablerequired

True when live DNS already serves exactly this value, so the record can be skipped. False when it is missing or serving something else. Null when the live lookup could not be completed, in which case "action" falls back to a static, type-derived value and should be treated as a best-effort hint.

domainDomainrequired
Domain
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
dmarc_optionsobjectrequired
properties
additional_emailsarray of string (email)required
legacy_ruf_emailsarray of string (email)
policyDmarcPolicyrequired
One of: none, quarantine, reject
pctnumberrequired
Min: 0 · Max: 100
spstring enumrequired
One of: none, quarantine, reject, same
strict_spfbooleanrequired
strict_dkimbooleanrequired
spf_optionsobjectrequired
properties
force_flatteningbooleanrequired
enabledbooleanrequired
mechanism_descriptionsobject
managed_dns_statusobjectrequired
properties
dmarcDnsStatusrequired
One of: unknown, syncing, ready, error
spfDnsStatusrequired
One of: unknown, syncing, ready, error
dkimDnsStatusrequired
One of: unknown, syncing, ready, error
bimiDnsStatusrequired
One of: unknown, syncing, ready, error
mta_stsDnsStatusrequired
One of: unknown, syncing, ready, error
managed_dns_status_sinceobjectrequired

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.

properties
dmarcstring (date-time), nullablerequired
spfstring (date-time), nullablerequired
dkimstring (date-time), nullablerequired
bimistring (date-time), nullablerequired
mta_stsstring (date-time), nullablerequired
monitoring_statusDmarcSetupStaterequired
One of: drifted, none, pending, setup, failed
monitoring_failure_reasonDmarcSetupFailureReasonrequired
One of: 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
monitoring_failure_detailDmarcSetupFailureDetailrequired
DmarcSetupFailureDetail
observedstring
expected_ruastring
from_hostnamestring
record_countnumber
monitoring_emailstringrequired
open_tasks_countnumberrequired

Open tickets on this domain. Opportunity tickets such as set_up_bimi are not counted, and expand[]=tasks leaves them out to match.

Min: 0
highest_open_task_priorityinteger, nullablerequired

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.

Min: 0 · Max: 3
scorenumberrequired
Min: 0 · Max: 100
score_bandstring enumrequired

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.

One of: critical, bad, good, great
is_parkedbooleanrequired
is_dmarc_managedbooleanrequired
is_spf_managedbooleanrequired
is_dkim_managedbooleanrequired
is_bimi_managedbooleanrequired
is_mta_sts_managedbooleanrequired
bimi_optionsobjectrequired
properties
enabledbooleanrequired
logostring (uri), nullablerequired
certificatestring (uri), nullablerequired
bimi_error_reasonManagedDnsErrorReasonrequired

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.

One of: setup_timeout, drift, certificate_invalid, record_conflict, delegation_missing, publish_failed, dkim_key_error, check_failed
dmarc_error_reasonManagedDnsErrorReason & objectrequired

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.

spf_error_reasonManagedDnsErrorReason & objectrequired

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.

dkim_error_reasonManagedDnsErrorReason & objectrequired

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.

mta_sts_error_reasonManagedDnsErrorReason & objectrequired

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.

dns_conflictsarray of DnsConflictrequired

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.

DnsConflict
labelstringrequired

The exact DNS name the conflicting records sit at.

protocolDnsConflictProtocolrequired
One of: dmarc, spf, bimi, mta_sts, dkim
kindDnsConflictKindrequired
One of: 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
summarystringrequired
rfcstringrequired

The specification clause the zone violates, e.g. "RFC 1034 §3.6.2".

consequencestringrequired

What this actually does to mail for this domain, in plain language.

remediationstringrequired

Which record to delete and which to keep, stated concretely enough to act on.

conflicting_recordsarray of stringrequired

The offending record values, verbatim as published.

authoritative_nameserversarray of objectrequired

Every authoritative nameserver queried and exactly what it returned.

items
nameserverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
public_resolversarray of objectrequired

Independent public resolvers queried and exactly what each returned.

items
resolverstringrequired
ipstringrequired
cnamearray of stringrequired
txtarray of stringrequired
answeredbooleanrequired
timed_outbooleanrequired
occurrence_countnumberrequired

How many detection runs have observed this conflict.

first_detected_atstring (date-time)required
last_detected_atstring (date-time)required
bimi_cname_targetstringrequired

The host a customer CNAMEs default._bimi.{domain} to for Palisade-served BIMI.

bimi_txt_valuestring, nullablerequired

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_spfstring, nullablerequired
last_14_days_volumenumberrequired
Min: 0
last_14_days_dmarc_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_spf_pass_pctnumberrequired
Min: 0 · Max: 100
last_14_days_dkim_pass_pctnumberrequired
Min: 0 · Max: 100
group_idstring (uuid), nullablerequired
registrarstring, nullablerequired
groupGroup
Group
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
domainsobject
properties
countnumberrequired
enforcement_pctnumberrequired
last_14_days_volumenumberrequired
last_14_days_dmarc_pass_pctnumberrequired
average_scorenumberrequired
created_atstring (date-time)required
updated_atstring (date-time)required
tasksarray of Task

Returns only tasks with status "open"

Task
idstring (uuid)required
domain_idstring (uuid)required
domainobject
properties
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
scorenumberrequired

The domain audit score as it stands now.

Min: 0 · Max: 100
score_gaininteger

How much of the domain score completing this ticket wins back, by the same scoring the domain overview shows. 0 for ticket types the score does not measure. Present only with expand[]=domain, since it depends on the domain as it stands now.

Min: 0
sending_domainstring, nullablerequired
source_idstring (uuid), nullablerequired
sourceobject
properties
idstring (uuid)required
namestringrequired
homepagestring (uri), nullablerequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
dkim_discovery_selectorsarray of stringrequired
instructionsobject, nullable

BETA: Only expandable for GET /tasks/:id. Can contain instructions sometimes.

properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
source_aliasstring, nullablerequired
prioritynumberrequired
sequencenumberrequired

Where the task sits in the email-authentication rollout, lower first: 10 DMARC setup, 20 foundation records, 30 SPF/DKIM alignment, 40 cleanup, 50 enforcement, 60 hardening. Separate from priority, which is urgency; sequence orders tasks of equal priority, since an alignment task cannot be worked before DMARC reporting exists to show the failure.

statusTaskStatusrequired
One of: open, snoozed, canceled, dismissed, pending, done
typeTaskTyperequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
descriptionstringrequired
snoozed_untilstring (date-time), nullablerequired
marked_pending_atstring (date-time), nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
resolution_reasonTaskResolutionReasonrequired

Why a done ticket closed. 'verified': Palisade's own check found the problem gone. 'manual': a person or an API caller marked it done and nothing was checked. Null on a ticket that is not done, and on one closed before the reason was first recorded. More values may be added, so treat an unknown one as unspecified.

One of: verified, manual
dmarc_setup_atstring (date-time), nullablerequired
dmarc_verified_atstring (date-time), nullablerequired

When the domain first reached the "setup" monitoring status and DMARC report collection began.

monitoring_sincestring, nullablerequired

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_atstring (date-time)required
updated_atstring (date-time)required

Get the remediation plan

GET/domains/{domainId}/planrequires auth

The work Palisade has planned for this domain, as the four stages of the DMARC journey with the steps each is made of. A step Palisade has already opened tickets for carries their ids in task_ids and is readable through GET /tasks; a step it has not carries none, and is work it expects to open later. upcoming_steps is the shortlist of what comes next, which is what the app shows under a domain's open tickets. Read /tasks for what is actionable now and this for what is coming. Computed on read, so nothing here is a stored record and none of it emits webhooks.

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/plan" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200DomainPlan

Success

Response body
scan_findingsobject, nullable

Saved onboarding findings, including those without an actionable ticket. Not a fresh DNS audit.

properties
scanned_atstring (date-time)required
itemsarray of objectrequired
items
idstringrequired
titlestringrequired
detailstringrequired
codestringrequired
statusstring enumrequired
One of: open, verifying, snoozed, ticket_completed, upcoming, waiting, optional, review
guidancestringrequired
tasksarray of objectrequired
items
idstring (uuid)required
statusstringrequired
task_typesarray of string enumrequired

The task types that would carry this finding out, matching "type" on the Task object and "task_type" on a plan step. A type listed here is not always opened: update_ttl and set_up_tls_rpt, for example, never are. Empty when no task type covers the finding, such as BIMI or a DKIM problem with one selector.

items
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
domain_idstring (uuid)required
domainstringrequired

The domain this plan is for.

is_parkedbooleanrequired

True when the domain is parked. A parked domain is monitored but has no journey to work through.

agent_proposals_enabledbooleanrequired

False when the plan is not being worked because the organization is on a plan without the agent. upcoming_steps is empty in that case, because Palisade will not open those tasks.

current_stageinteger, nullablerequired

The number of the stage being worked now, or null when none is current.

stagesarray of PlanStagerequired

The four stages of the DMARC journey, in order.

PlanStage
numberintegerrequired

Position in the journey, 1 through 4.

keystringrequired

Stable identifier: "setup", "alignment", "enforcement" or "monitoring".

titlestringrequired
descriptionstringrequired
statusPlanStageStatusrequired

"completed" when the stage is done, "current" for the one being worked, "pending" for one not started.

One of: completed, current, pending
stepsarray of PlanSteprequired

The work this stage is made of. Empty for a parked domain.

PlanStep
keystringrequired

Stable identifier for this step, safe to branch on - for example "dmarc-setup", "alignment-spf" or "dmarc-reject-full". Steps are added over time; existing keys keep their meaning.

task_typestring enum, nullablerequired

The type of task this step opens as, matching "type" on the Task object. Null for a step that is never a task, such as ongoing monitoring.

One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
titlestringrequired

What the step asks for, in plain language.

descriptionstringrequired

Why the step matters.

priorityintegerrequired

Severity on the same scale as a task: 0 critical, 1 high, 2 medium, 3 low. When tasks already exist for this step, this is the most severe of theirs.

score_gainintegerrequired

How many points of the domain's audit score completing this step would win back. 0 when none.

statusPlanStepStatusrequired

"in_progress" when Palisade has already opened tasks for this step, listed in task_ids. "upcoming" when it has not, meaning there is nothing to action yet.

One of: in_progress, upcoming
task_idsarray of string (uuid)required

Open and pending tasks that carry out this step, readable through GET /tasks/{id}. Empty for an upcoming step. A step covering sending sources has one task per source, so this can hold several.

optional_stepsarray of PlanOptionalSteprequired

Improvements worth making at this stage that Palisade does not require.

PlanOptionalStep
keystringrequired

Stable identifier for the optional step, for example "enable-hosted-spf".

titlestringrequired
descriptionstringrequired
recommendedbooleanrequired

True when Palisade actively suggests it for this domain right now.

upcoming_stepsarray of PlanSteprequired

The steps Palisade expects to work next: the next stage's steps, when that stage has not started. These are a subset of stages[].steps, always with status "upcoming", and are what the app shows below the open tasks. Empty for a parked domain, when the agent is not proposing work, and once the journey is finished.

PlanStep
keystringrequired

Stable identifier for this step, safe to branch on - for example "dmarc-setup", "alignment-spf" or "dmarc-reject-full". Steps are added over time; existing keys keep their meaning.

task_typestring enum, nullablerequired

The type of task this step opens as, matching "type" on the Task object. Null for a step that is never a task, such as ongoing monitoring.

One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
titlestringrequired

What the step asks for, in plain language.

descriptionstringrequired

Why the step matters.

priorityintegerrequired

Severity on the same scale as a task: 0 critical, 1 high, 2 medium, 3 low. When tasks already exist for this step, this is the most severe of theirs.

score_gainintegerrequired

How many points of the domain's audit score completing this step would win back. 0 when none.

statusPlanStepStatusrequired

"in_progress" when Palisade has already opened tasks for this step, listed in task_ids. "upcoming" when it has not, meaning there is nothing to action yet.

One of: in_progress, upcoming
task_idsarray of string (uuid)required

Open and pending tasks that carry out this step, readable through GET /tasks/{id}. Empty for an upcoming step. A step covering sending sources has one task per source, so this can hold several.

DomainSource

List confirmed senders

GET/domains/{domainId}/sourcesrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/sources" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of DomainSourcerequired
DomainSource
idstring (uuid)required
is_knownbooleanrequired
source_idstring, nullablerequired

The catalogue source this sender was matched to, or null when it is not one Palisade recognises. Lets a caller line a sender up with the SPF include or DKIM key it belongs to.

spf_valuestring, nullablerequired

The SPF mechanism discovery observed for this sender, when it saw one.

source_namestring, nullablerequired
source_homepagestring, nullablerequired
sending_domainstring, nullablerequired
dkim_selectorsarray of stringrequired
confirmation_statusstring enumrequired
One of: confirmed, discarded, requires_confirmation
confirmed_atstring (date-time), nullablerequired
last_seen_atstring, nullablerequired

The last day (YYYY-MM-DD) this sender was seen sending for the domain, across all recorded history rather than a recent window, so a sender silent for a year still reports the day it went quiet. Null when no sending has been recorded for it yet. Reported from daily aggregates that can trail live reporting by a few days, so treat it as a date rather than a timestamp. Only counts sending observed since the domain was added to Palisade.

last_spf_aligned_atstring, nullablerequired

The last day (YYYY-MM-DD) mail from this sender passed aligned SPF for the domain. Distinct from last_seen_at: a sender that still sends but no longer passes SPF has an SPF problem, not a disused include. Null when it has never passed aligned SPF in recorded history.

totalsobjectrequired
properties
compliantnumberrequired
non_compliantnumberrequired
forwardednumberrequired
unknownnumberrequired
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Confirm or update a sender

POST/domains/{domainId}/sources/{sourceId}requires auth

Path parameters

domainIdstring (uuid)required
sourceIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

confirmation_statusstring enumrequired
One of: confirmed, discarded, requires_confirmation

Example request

curl -X POST "https://api.palisade.email/domains/<domainId>/sources/<sourceId>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "confirmation_status": "confirmed"
}'

Responses

200DomainSource

Success

Response body
idstring (uuid)required
is_knownbooleanrequired
source_idstring, nullablerequired

The catalogue source this sender was matched to, or null when it is not one Palisade recognises. Lets a caller line a sender up with the SPF include or DKIM key it belongs to.

spf_valuestring, nullablerequired

The SPF mechanism discovery observed for this sender, when it saw one.

source_namestring, nullablerequired
source_homepagestring, nullablerequired
sending_domainstring, nullablerequired
dkim_selectorsarray of stringrequired
confirmation_statusstring enumrequired
One of: confirmed, discarded, requires_confirmation
confirmed_atstring (date-time), nullablerequired
last_seen_atstring, nullablerequired

The last day (YYYY-MM-DD) this sender was seen sending for the domain, across all recorded history rather than a recent window, so a sender silent for a year still reports the day it went quiet. Null when no sending has been recorded for it yet. Reported from daily aggregates that can trail live reporting by a few days, so treat it as a date rather than a timestamp. Only counts sending observed since the domain was added to Palisade.

last_spf_aligned_atstring, nullablerequired

The last day (YYYY-MM-DD) mail from this sender passed aligned SPF for the domain. Distinct from last_seen_at: a sender that still sends but no longer passes SPF has an SPF problem, not a disused include. Null when it has never passed aligned SPF in recorded history.

totalsobjectrequired
properties
compliantnumberrequired
non_compliantnumberrequired
forwardednumberrequired
unknownnumberrequired

DkimKey

List DKIM keys

GET/domains/{domainId}/dkim-keysrequires auth

Path parameters

domainIdstring (uuid)required

Query parameters

selectorstring
dns_statusDnsStatus
One of: unknown, syncing, ready, error
pagenumber
per_pagenumber

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/dkim-keys" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of DkimKeyrequired
DkimKey
idstring (uuid)required
selectorstringrequired
record_typestring enumrequired
One of: TXT, CNAME
valuestringrequired
dns_statusDnsStatusrequired
One of: unknown, syncing, ready, error
publish_errorstring, nullablerequired

Why the last publish attempt failed, in terms a customer can act on. Null unless dns_status is error; cleared by the next successful publish.

ttlnumber, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
last_published_atstring (date-time), nullablerequired
deleted_atstring (date-time), nullablerequired
created_bystring, nullablerequired
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Add a DKIM key

POST/domains/{domainId}/dkim-keysrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

selectorstringrequired
Min length: 1
record_typestring enumrequired
One of: TXT, CNAME
valuestringrequired
Min length: 1
ttlnumber
Min: 300 · Max: 86400

Example request

curl -X POST "https://api.palisade.email/domains/<domainId>/dkim-keys" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "selector": "string",
  "record_type": "TXT",
  "value": "string",
  "ttl": 300
}'

Responses

200DkimKey

Success

Response body
idstring (uuid)required
selectorstringrequired
record_typestring enumrequired
One of: TXT, CNAME
valuestringrequired
dns_statusDnsStatusrequired
One of: unknown, syncing, ready, error
publish_errorstring, nullablerequired

Why the last publish attempt failed, in terms a customer can act on. Null unless dns_status is error; cleared by the next successful publish.

ttlnumber, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
last_published_atstring (date-time), nullablerequired
deleted_atstring (date-time), nullablerequired
created_bystring, nullablerequired

Get a DKIM key

GET/domains/{domainId}/dkim-keys/{id}requires auth

Path parameters

domainIdstring (uuid)required
idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/dkim-keys/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200DkimKey

Success

Response body
idstring (uuid)required
selectorstringrequired
record_typestring enumrequired
One of: TXT, CNAME
valuestringrequired
dns_statusDnsStatusrequired
One of: unknown, syncing, ready, error
publish_errorstring, nullablerequired

Why the last publish attempt failed, in terms a customer can act on. Null unless dns_status is error; cleared by the next successful publish.

ttlnumber, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
last_published_atstring (date-time), nullablerequired
deleted_atstring (date-time), nullablerequired
created_bystring, nullablerequired

Update a DKIM key

POST/domains/{domainId}/dkim-keys/{id}requires auth

Path parameters

domainIdstring (uuid)required
idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

selectorstring
Min length: 1
record_typestring enum
One of: TXT, CNAME
valuestring
Min length: 1
ttlnumber
Min: 300 · Max: 86400

Example request

curl -X POST "https://api.palisade.email/domains/<domainId>/dkim-keys/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "selector": "string",
  "record_type": "TXT",
  "value": "string",
  "ttl": 300
}'

Responses

200DkimKey

Success

Response body
idstring (uuid)required
selectorstringrequired
record_typestring enumrequired
One of: TXT, CNAME
valuestringrequired
dns_statusDnsStatusrequired
One of: unknown, syncing, ready, error
publish_errorstring, nullablerequired

Why the last publish attempt failed, in terms a customer can act on. Null unless dns_status is error; cleared by the next successful publish.

ttlnumber, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
last_published_atstring (date-time), nullablerequired
deleted_atstring (date-time), nullablerequired
created_bystring, nullablerequired

Delete a DKIM key

DELETE/domains/{domainId}/dkim-keys/{id}requires auth

Path parameters

domainIdstring (uuid)required
idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/domains/<domainId>/dkim-keys/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

Reports

Get the DMARC summary

GET/domains/{domainId}/reports/summaryrequires auth

Path parameters

domainIdstring (uuid)required

Query parameters

periodstring enum

Reporting window, ending yesterday. Defaults to last_7_days.

One of: last_7_days, last_14_days, last_30_days

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/reports/summary" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200DmarcSummary

Success

Response body
domain_idstring (uuid)required

Id of the domain the summary is for.

domainstringrequired

The domain name the summary is for.

date_fromstringrequired

First day of the window, YYYY-MM-DD. Clamped to the earliest day the organization's plan retains report history for, so it can be later than the requested period alone implies.

date_tostringrequired

Last day of the window, YYYY-MM-DD. Always yesterday: aggregate reports arrive a day in arrears, so a window ending today would read as a volume collapse.

volumeintegerrequired

Total messages reported in the window, across every compliance bucket.

dmarc_pass_pctnumberrequired

Share of volume that passed DMARC, 0-100, rounded to two decimals, and 0 when the window has no volume. The denominator is volume, so forwarded and uncategorised traffic counts against it - which is why this reads lower than the last_14_days figure.

spf_pass_pctnumberrequired

Share of volume that passed SPF, 0-100, rounded to two decimals, and 0 when the window has no volume.

dkim_pass_pctnumberrequired

Share of volume that passed DKIM, 0-100, rounded to two decimals, and 0 when the window has no volume.

totalsobjectrequired

Message counts by compliance bucket. They sum to volume.

properties
compliantintegerrequired

Messages that passed DMARC alignment.

non_compliantintegerrequired

Messages that failed DMARC. This is the number to drive to zero.

forwardedintegerrequired

Messages the compliance categorizer attributed to forwarding.

unknownintegerrequired

Messages from a sending source Palisade could not identify.

undeterminedintegerrequired

Messages whose compliance is undetermined, including reports the categorizer has not processed yet.

previous_periodobjectrequired

The same number of days immediately before this window. It ends the day before this window starts, so its date_to is not yesterday.

properties
date_fromstringrequired

First day of the window, YYYY-MM-DD. Clamped to the earliest day the organization's plan retains report history for, so it can be later than the requested period alone implies.

date_tostringrequired

Last day of the window, YYYY-MM-DD. No window ever includes today: aggregate reports arrive a day in arrears, so a window ending today would read as a volume collapse.

volumeintegerrequired

Total messages reported in the window, across every compliance bucket.

dmarc_pass_pctnumberrequired

Share of volume that passed DMARC, 0-100, rounded to two decimals, and 0 when the window has no volume. The denominator is volume, so forwarded and uncategorised traffic counts against it - which is why this reads lower than the last_14_days figure.

spf_pass_pctnumberrequired

Share of volume that passed SPF, 0-100, rounded to two decimals, and 0 when the window has no volume.

dkim_pass_pctnumberrequired

Share of volume that passed DKIM, 0-100, rounded to two decimals, and 0 when the window has no volume.

changeobjectrequired

This window minus the previous one. Positive means the metric improved (or grew, for volume).

properties
volumeintegerrequired

Change in message volume against the previous window.

dmarc_pass_pctnumberrequired

Change in DMARC pass rate, in percentage points, rounded to two decimals.

spf_pass_pctnumberrequired

Change in SPF pass rate, in percentage points, rounded to two decimals.

dkim_pass_pctnumberrequired

Change in DKIM pass rate, in percentage points, rounded to two decimals.

last_14_daysobjectrequired

The stored 14-day figures GET /domains/{id} reports. These count only compliant and non-compliant traffic, so they read higher than the window figures above on a domain with forwarding. A mismatch is the two definitions, not a fault.

properties
volumeintegerrequired

Messages counted over the last 14 days, as stored on the domain.

dmarc_pass_pctnumberrequired

Share of that volume that passed DMARC, 0-100.

spf_pass_pctnumberrequired

Share of that volume that passed SPF, 0-100.

dkim_pass_pctnumberrequired

Share of that volume that passed DKIM, 0-100.

dmarc_policystringrequired

The domain's DMARC policy state, in the same form GET /domains/{id} reports.

monitoring_statusstringrequired

Monitoring state of the domain, in the same form GET /domains/{id} reports.

policy_readinessobjectrequired

Whether Palisade currently recommends tightening the DMARC policy. This reports the recommendation Palisade has already computed - it is not a second, independent gate.

properties
statusstring enumrequired

"advance_recommended" when Palisade has an open policy-advancement task for the domain, "hold" when it has not opened one, and "at_maximum" when the domain is already at p=reject with pct=100.

One of: advance_recommended, hold, at_maximum
reasonstringrequired

Why Palisade does or does not recommend tightening the policy right now. When status is "advance_recommended", this is the advancement task's own description.

open_task_idstring (uuid), nullablerequired

The UPDATE_DMARC_RECORD task carrying the recommendation, when Palisade has opened one.

open_tasksarray of DmarcProbeTaskrequired

Open and pending remediation tasks for this domain, most urgent first, capped at 10.

DmarcProbeTask
idstring (uuid)required

Task id. Read it with GET /tasks/{id}?expand[]=instructions for the fix Palisade has worked out.

typestring enumrequired

What kind of problem the task describes.

One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
priorityintegerrequired

Lower is more urgent. 0 is the most urgent.

descriptionstringrequired

What is wrong, in plain language.

source_aliasstring, nullablerequired

The sending source this task covers. Matches senders[].source_alias.

sending_domainstring, nullablerequired

The sending domain the task is about, when it has one.

open_tasks_countintegerrequired

Total open and pending tasks, which may exceed the array length.

next_stepstringrequired

The single action Palisade suggests taking next.

List DMARC senders

GET/domains/{domainId}/reports/sendersrequires auth

Path parameters

domainIdstring (uuid)required

Query parameters

periodstring enum

Reporting window, ending yesterday. Defaults to last_7_days.

One of: last_7_days, last_14_days, last_30_days
limitinteger

How many senders to return, highest volume first. Maximum 20.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/reports/senders" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200DmarcSenders

Success

Response body
domain_idstring (uuid)required
domainstringrequired
date_fromstringrequired
date_tostringrequired
volumeintegerrequired

Total windowed volume across every sender, not just the ones returned.

total_sendersintegerrequired

Distinct senders seen in the window.

truncatedbooleanrequired

True when total_senders exceeds the returned list.

sendersarray of DmarcSenderrequired
DmarcSender
source_aliasstringrequired

Stable identifier for the sending source: a Palisade source id when the sender is recognised, otherwise the sending base domain, or "unknown". This is the key that links a sender to a task.

namestringrequired

Display name when the source is recognised, otherwise source_alias.

source_idstring (uuid), nullablerequired
is_knownbooleanrequired

False when DMARC reports show this sender but Palisade cannot identify it.

sending_domainsarray of stringrequired

The header-from domains this source sent as, highest volume first, capped at 5.

volumeintegerrequired
volume_share_pctnumberrequired

Share of the domain's total windowed volume this sender accounts for.

dmarc_pass_pctnumberrequired
spf_pass_pctnumberrequired
dkim_pass_pctnumberrequired
totalsobjectrequired

Message counts by compliance bucket. They sum to volume.

properties
compliantintegerrequired

Messages that passed DMARC alignment.

non_compliantintegerrequired

Messages that failed DMARC. This is the number to drive to zero.

forwardedintegerrequired

Messages the compliance categorizer attributed to forwarding.

unknownintegerrequired

Messages from a sending source Palisade could not identify.

undeterminedintegerrequired

Messages whose compliance is undetermined, including reports the categorizer has not processed yet.

is_failingbooleanrequired

True when the sender has non-compliant volume in the window.

open_task_idstring (uuid), nullablerequired

An open or pending remediation task covering this sender, when one exists. Call GET /tasks/{id}?expand[]=instructions for the fix rather than improvising one.

open_task_typestring enum, nullablerequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
next_stepstringrequired

DnsProvider

Detect the DNS provider

GET/dns-providers/detectrequires auth

Detect which DNS provider hosts a domain, from its live NS records. Returns a null provider when the nameservers match no known provider.

Query parameters

domainstringrequired

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/dns-providers/detect" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
providerstring, nullablerequired

DnsSnapshot

List DNS snapshots

GET/domains/{domainId}/dns-snapshotsrequires auth

Path parameters

domainIdstring (uuid)required

Query parameters

from_datestring (date-time)
to_datestring (date-time)
record_typesarray of string enum
One of: spf, dmarc, bimi, mx, dkim, ns, mta_sts, tls_rpt
pagenumber
per_pagenumber

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/dns-snapshots" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of objectrequired
items
idstring (uuid)required
spfarray of stringrequired
dmarcarray of stringrequired
bimiarray of stringrequired
mxarray of objectrequired
items
exchangestringrequired
prioritynumberrequired
dkimarray of objectrequired
items
selectorstringrequired
valuestringrequired
nsarray of stringrequired
mta_stsarray of stringrequired
tls_rptarray of stringrequired
records_updatedarray of stringrequired
created_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Get a DNS snapshot

GET/domains/{domainId}/dns-snapshots/{id}requires auth

Path parameters

domainIdstring (uuid)required
idstring (uuid)required

Query parameters

expandarray of string enum
One of: diff

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/dns-snapshots/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200DnsSnapshot

Success

Response body
idstring (uuid)required
spfarray of stringrequired
dmarcarray of stringrequired
bimiarray of stringrequired
mxarray of objectrequired
items
exchangestringrequired
prioritynumberrequired
dkimarray of objectrequired
items
selectorstringrequired
valuestringrequired
nsarray of stringrequired
mta_stsarray of stringrequired
tls_rptarray of stringrequired
records_updatedarray of stringrequired
created_atstring (date-time)required
diffobject, nullable
properties
spfarray of object
items
oldstring, nullablerequired
newstring, nullablerequired
dmarcarray of object
items
oldstring, nullablerequired
newstring, nullablerequired
bimiarray of object
items
oldstring, nullablerequired
newstring, nullablerequired
mxarray of object
items
oldobject, nullablerequired
properties
exchangestringrequired
prioritynumberrequired
newobject, nullablerequired
properties
exchangestringrequired
prioritynumberrequired
dkimarray of object
items
oldobject, nullablerequired
properties
selectorstringrequired
valuestringrequired
newobject, nullablerequired
properties
selectorstringrequired
valuestringrequired
nsarray of object
items
oldstring, nullablerequired
newstring, nullablerequired
mta_stsarray of object
items
oldstring, nullablerequired
newstring, nullablerequired
tls_rptarray of object
items
oldstring, nullablerequired
newstring, nullablerequired

Group

List groups

GET/groupsrequires auth

Query parameters

querystring
sortstring enum
One of: created_at, name
sort_directionstring enum
One of: desc, asc
per_pagenumber
pagenumber
expandarray of string enum
One of: domains

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/groups" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of Grouprequired
Group
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
domainsobject
properties
countnumberrequired
enforcement_pctnumberrequired
last_14_days_volumenumberrequired
last_14_days_dmarc_pass_pctnumberrequired
average_scorenumberrequired
created_atstring (date-time)required
updated_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Create a group

POST/groupsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

namestringrequired
Min length: 1

Example request

curl -X POST "https://api.palisade.email/groups" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

Responses

200object

Success

Response body
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required

Get a group

GET/groups/{id}

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/groups/<id>"

Responses

200Group

Success

Response body
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
domainsobject
properties
countnumberrequired
enforcement_pctnumberrequired
last_14_days_volumenumberrequired
last_14_days_dmarc_pass_pctnumberrequired
average_scorenumberrequired
created_atstring (date-time)required
updated_atstring (date-time)required

Update a group

POST/groups/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

namestring
Min length: 1
external_customer_idstring, nullable
external_billing_entity_idstring, nullable
backfill_ticketsboolean

Example request

curl -X POST "https://api.palisade.email/groups/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "external_customer_id": "string",
  "external_billing_entity_id": "string",
  "backfill_tickets": true
}'

Responses

200object

Success

Response body
idstring (uuid)required
namestringrequired
external_customer_idstring, nullablerequired
external_billing_entity_idstring, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required

Delete a group

DELETE/groups/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/groups/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Deleted

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

Invitation

List pending invitations

GET/invitationsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/invitations" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of Invitationrequired
Invitation
idstring (uuid)required
inviteeobjectrequired
properties
emailstring (email)required
rolesarray of string enumrequired
items
One of: admin, editor, viewer
groupsarray of string (uuid)
Default: []
inviter_namestringrequired
created_atstringrequired
expires_atstringrequired
urlstring (uri)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Invite a teammate

POST/invitationsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

emailstring (email)required

The address to invite.

rolesarray of string enumrequired
items
One of: admin, editor, viewer
groupsarray of string (uuid)
ttl_secnumber
Default: 1209600 · Min: 86400 · Max: 2592000

Example request

curl -X POST "https://api.palisade.email/invitations" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "user@example.com",
  "roles": [
    "admin"
  ],
  "groups": [
    "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
  ],
  "ttl_sec": 1209600
}'

Responses

201object

Created

Response body
dataInvitationrequired
Invitation
idstring (uuid)required
inviteeobjectrequired
properties
emailstring (email)required
rolesarray of string enumrequired
items
One of: admin, editor, viewer
groupsarray of string (uuid)
Default: []
inviter_namestringrequired
created_atstringrequired
expires_atstringrequired
urlstring (uri)required
422InvitationDomainNotAllowed | InvitationInviteeExists

invitation_domain_not_allowed: API-key callers only, the invitee email domain does not match any existing member email domain of the organization; contact support to add a new domain, and note that dashboard sessions are not subject to this check. invitation_invitee_exists: the email address already has a Palisade account, so an invitation would send it to a signup screen it cannot complete; use POST /members to add the existing account instead.

Response body
InvitationDomainNotAllowed | InvitationInviteeExists
502InvitationUpstreamFailure

upstream_failure: the identity provider returned an error while creating the invitation. The invitation may still have been created without its email being sent; list invitations to check before retrying, since a retry creates a second invitation to the same address.

Response body
codestring enumrequired
One of: upstream_failure
messagestringrequired

Resend an invitation

POST/invitations/{id}/resendrequires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/invitations/<id>/resend" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

204object

No Content

Response body
502InvitationUpstreamFailure

upstream_failure: the identity provider returned an error while replacing the invitation. The message says whether the old invitation still stands, was removed, or could not be checked; list invitations before retrying.

Response body
codestring enumrequired
One of: upstream_failure
messagestringrequired

Revoke an invitation

DELETE/invitations/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/invitations/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Deleted

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

Task

List tasks

GET/tasksrequires auth

By default, the API returns 'open' and 'pending' tickets. To filter by other statuses, use the 'statuses' query parameter.

Query parameters

statusesarray of TaskStatus

By default, we return OPEN and PENDING tasks.

One of: open, snoozed, canceled, dismissed, pending, done
sortstring enum

Defaults to 'priority', most urgent first, with ties broken by rollout stage then recency — so among equally urgent tickets, DMARC setup comes before the SPF and DKIM work that depends on its reports. 'sequence' walks the rollout outright: DMARC setup, foundation records, SPF/DKIM alignment, cleanup, enforcement, hardening. 'status' ranks pending tickets first, then open, snoozed, done, dismissed and canceled, breaking ties by priority, sequence, then most recent. 'resolved_at' orders by when a ticket was completed, most recent first when descending; tickets never completed sort last.

One of: created_at, priority, resolved_at, sequence, status
sort_directionstring enum
One of: desc, asc
per_pagenumber
pagenumber
domainstring (uuid)
groupstring (uuid)
expandarray of string enum
One of: domain, source

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/tasks" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of Taskrequired
Task
idstring (uuid)required
domain_idstring (uuid)required
domainobject
properties
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
scorenumberrequired

The domain audit score as it stands now.

Min: 0 · Max: 100
score_gaininteger

How much of the domain score completing this ticket wins back, by the same scoring the domain overview shows. 0 for ticket types the score does not measure. Present only with expand[]=domain, since it depends on the domain as it stands now.

Min: 0
sending_domainstring, nullablerequired
source_idstring (uuid), nullablerequired
sourceobject
properties
idstring (uuid)required
namestringrequired
homepagestring (uri), nullablerequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
valuestring
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
dkim_discovery_selectorsarray of stringrequired
instructionsobject, nullable

BETA: Only expandable for GET /tasks/:id. Can contain instructions sometimes.

properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
source_aliasstring, nullablerequired
prioritynumberrequired
sequencenumberrequired

Where the task sits in the email-authentication rollout, lower first: 10 DMARC setup, 20 foundation records, 30 SPF/DKIM alignment, 40 cleanup, 50 enforcement, 60 hardening. Separate from priority, which is urgency; sequence orders tasks of equal priority, since an alignment task cannot be worked before DMARC reporting exists to show the failure.

statusTaskStatusrequired
One of: open, snoozed, canceled, dismissed, pending, done
typeTaskTyperequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
descriptionstringrequired
snoozed_untilstring (date-time), nullablerequired
marked_pending_atstring (date-time), nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
resolution_reasonTaskResolutionReasonrequired

Why a done ticket closed. 'verified': Palisade's own check found the problem gone. 'manual': a person or an API caller marked it done and nothing was checked. Null on a ticket that is not done, and on one closed before the reason was first recorded. More values may be added, so treat an unknown one as unspecified.

One of: verified, manual
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Get a task

GET/tasks/{id}requires auth

Path parameters

idstring (uuid)required

Query parameters

expandarray of string enum
One of: domain, instructions, source

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/tasks/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200Task

Success

Response body
idstring (uuid)required
domain_idstring (uuid)required
domainobject
properties
idstring (uuid)required
urlstringrequired
dmarc_policystringrequired
scorenumberrequired

The domain audit score as it stands now.

Min: 0 · Max: 100
score_gaininteger

How much of the domain score completing this ticket wins back, by the same scoring the domain overview shows. 0 for ticket types the score does not measure. Present only with expand[]=domain, since it depends on the domain as it stands now.

Min: 0
sending_domainstring, nullablerequired
source_idstring (uuid), nullablerequired
sourceobject
properties
idstring (uuid)required
namestringrequired
homepagestring (uri), nullablerequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
valuestring
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
dkim_discovery_selectorsarray of stringrequired
instructionsobject, nullable

BETA: Only expandable for GET /tasks/:id. Can contain instructions sometimes.

properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
source_aliasstring, nullablerequired
prioritynumberrequired
sequencenumberrequired

Where the task sits in the email-authentication rollout, lower first: 10 DMARC setup, 20 foundation records, 30 SPF/DKIM alignment, 40 cleanup, 50 enforcement, 60 hardening. Separate from priority, which is urgency; sequence orders tasks of equal priority, since an alignment task cannot be worked before DMARC reporting exists to show the failure.

statusTaskStatusrequired
One of: open, snoozed, canceled, dismissed, pending, done
typeTaskTyperequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
descriptionstringrequired
snoozed_untilstring (date-time), nullablerequired
marked_pending_atstring (date-time), nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
resolution_reasonTaskResolutionReasonrequired

Why a done ticket closed. 'verified': Palisade's own check found the problem gone. 'manual': a person or an API caller marked it done and nothing was checked. Null on a ticket that is not done, and on one closed before the reason was first recorded. More values may be added, so treat an unknown one as unspecified.

One of: verified, manual

Update a task

POST/tasks/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

statusTaskStatus
One of: open, snoozed, canceled, dismissed, pending, done
ignore_spfboolean

Stops counting the ticket's sender against SPF on its domain. Ignoring both SPF and DKIM for the ticket's sender discards it, which answers the sender's confirm_source ticket: a confirm_source ticket updated so that both are ignored is closed as done unless the status sent is dismissed or canceled, and any other open confirm_source ticket for the same sender closes as well.

ignore_dkimboolean

Stops counting the ticket's sender against DKIM on its domain. Ignoring both SPF and DKIM for the ticket's sender discards it, which answers the sender's confirm_source ticket: a confirm_source ticket updated so that both are ignored is closed as done unless the status sent is dismissed or canceled, and any other open confirm_source ticket for the same sender closes as well.

confirm_sourceboolean

Confirms the ticket's sender for its domain. That answers the sender's confirm_source ticket, so a confirm_source ticket updated with this flag is closed as done unless the status sent is dismissed or canceled, and any other open confirm_source ticket for the same sender closes as well.

confirm_source_in_useboolean

Example request

curl -X POST "https://api.palisade.email/tasks/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "open",
  "ignore_spf": true,
  "ignore_dkim": true,
  "confirm_source": true,
  "confirm_source_in_use": true
}'

Responses

200object

Success

Response body
idstring (uuid)required
domain_idstring (uuid)required
sending_domainstring, nullablerequired
source_idstring (uuid), nullablerequired
source_aliasstring, nullablerequired
prioritynumberrequired
sequencenumberrequired

Where the task sits in the email-authentication rollout, lower first: 10 DMARC setup, 20 foundation records, 30 SPF/DKIM alignment, 40 cleanup, 50 enforcement, 60 hardening. Separate from priority, which is urgency; sequence orders tasks of equal priority, since an alignment task cannot be worked before DMARC reporting exists to show the failure.

statusTaskStatusrequired
One of: open, snoozed, canceled, dismissed, pending, done
typeTaskTyperequired
One of: cleanup_spf_record, confirm_source, lockdown_domain, reduce_spf_lookups, set_up_dmarc_record, source_failing_dkim, source_failing_spf, set_up_mx_record, set_up_spf_record, update_dmarc_record, update_ttl, set_up_mta_sts, set_up_tls_rpt, resolve_dns_conflict, review_unused_sender, cleanup_sender_records, fix_mx_certificate, renew_vmc_certificate, dkim_selector_not_imported, set_up_bimi
descriptionstringrequired
snoozed_untilstring (date-time), nullablerequired
marked_pending_atstring (date-time), nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
resolution_reasonTaskResolutionReasonrequired

Why a done ticket closed. 'verified': Palisade's own check found the problem gone. 'manual': a person or an API caller marked it done and nothing was checked. Null on a ticket that is not done, and on one closed before the reason was first recorded. More values may be added, so treat an unknown one as unspecified.

One of: verified, manual

Organization

Create an organization

POST/organizationsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

namestringrequired
Min length: 3 · Max length: 128
invite_emailstring (email), nullablerequired

If provided, an invitation will be sent to this email to join the organization as an admin.

refererstring, nullable

This field should be omitted or kept null when using an API key.

pricing_typestring enum

Self-serve plan to provision. Only honored when PLG is enabled; otherwise the default plan is used.

One of: free, it_teams, msp
attribution_idstring (uuid)

Opaque first-party journey id carried from palisade.email. Ignored for non-self-serve creation.

Example request

curl -X POST "https://api.palisade.email/organizations" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "invite_email": "user@example.com",
  "referer": "string",
  "pricing_type": "free",
  "attribution_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
}'

Responses

200CreatedOrganization

Success

Response body
idstringrequired
namestringrequired
logo_urlstring, nullablerequired
emailstring, nullablerequired
phone_numberstring, nullablerequired
websitestring, nullablerequired
is_activebooleanrequired
require_mfabooleanrequired

Whether every member must complete multi-factor authentication to sign in to this organization. A member who has not set up an authenticator is asked to at their next sign-in.

settingsobject, nullable
properties
email_notificationsobject

Email notification preferences for the organization. Controls which types of emails are sent.

properties
domain_driftedboolean

Send notifications when domain DNS records drift from expected configuration.

Default: true
domain_failedboolean

Send notifications when a domain fails DMARC validation checks.

Default: true
domain_setupboolean

Send notifications when a domain DMARC configuration is successfully set up.

Default: true
tasks_digestsboolean

Send daily digest of new and pending tasks.

Default: true
setup_remindersboolean

Send reminders to finish adding and verifying a first domain.

Default: true
first_reportboolean

Send an email when a newly set-up domain's first DMARC data arrives, and its first report a week later.

Default: true
invitation_remindersboolean

Remind invitees about an unaccepted invitation, and tell the inviter which invitations are about to expire.

Default: true
billing_noticesboolean

Send plan-usage notices, such as passing the Free plan monthly email allowance.

Default: true
hosted_spf_liveboolean

Send a one-time email when a domain's Hosted SPF setup finishes and starts serving.

Default: true
delegation_missingboolean

Send a notification when a domain never delegated to a record Palisade hosts for it, so the hosted record is not serving. Controlled separately from domain_drifted.

Default: true
onboarding_dismissed_atstring (date-time), nullable

When someone dismissed or finished the onboarding wizard for this organization. Absent or null means nobody has, and the wizard is still offered to an organization with no domains.

created_atstring (date-time)required
updated_atstring (date-time)required
support_providerSupportProviderrequired
One of: palisade, sherweb
has_domainsboolean
invitation_failureOrganizationInvitationFailure

Present only when invite_email was given and the identity provider returned an error while creating that invitation. The organization itself was created. The message says whether the invitation was created anyway, was not created, or could not be checked; list the organization's invitations before inviting the address again, since a retry creates a second invitation.

OrganizationInvitationFailure
codestring enumrequired
One of: upstream_failure
messagestringrequired

Update an organization

POST/organizations/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

is_activeboolean

Whether or not the organization should be active.

namestring
Min length: 3 · Max length: 128
logo_urlstring (uri)
emailstring (email)

Organization contact email address.

phone_numberstring

Organization contact phone number.

Min length: 1 · Max length: 50
websitestring (uri)

Organization website URL.

settingsobject

Organization settings including email notification preferences.

properties
email_notificationsobject

Email notification preferences for the organization. Controls which types of emails are sent.

properties
domain_driftedboolean

Send notifications when domain DNS records drift from expected configuration.

Default: true
domain_failedboolean

Send notifications when a domain fails DMARC validation checks.

Default: true
domain_setupboolean

Send notifications when a domain DMARC configuration is successfully set up.

Default: true
tasks_digestsboolean

Send daily digest of new and pending tasks.

Default: true
setup_remindersboolean

Send reminders to finish adding and verifying a first domain.

Default: true
first_reportboolean

Send an email when a newly set-up domain's first DMARC data arrives, and its first report a week later.

Default: true
invitation_remindersboolean

Remind invitees about an unaccepted invitation, and tell the inviter which invitations are about to expire.

Default: true
billing_noticesboolean

Send plan-usage notices, such as passing the Free plan monthly email allowance.

Default: true
hosted_spf_liveboolean

Send a one-time email when a domain's Hosted SPF setup finishes and starts serving.

Default: true
delegation_missingboolean

Send a notification when a domain never delegated to a record Palisade hosts for it, so the hosted record is not serving. Controlled separately from domain_drifted.

Default: true
require_mfaboolean

Require every member to complete multi-factor authentication at each sign-in. Only an administrator of this organization can change it, from a signed-in session rather than an API key, and changing it in either direction is refused with mfa_confirmation_required until that administrator's own sign-in has completed multi-factor authentication.

Example request

curl -X POST "https://api.palisade.email/organizations/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "is_active": true,
  "name": "string",
  "logo_url": "https://example.com",
  "email": "user@example.com",
  "phone_number": "string",
  "website": "https://example.com",
  "settings": {
    "email_notifications": {
      "domain_drifted": true,
      "domain_failed": true,
      "domain_setup": true,
      "tasks_digests": true,
      "setup_reminders": true,
      "first_report": true,
      "invitation_reminders": true,
      "billing_notices": true,
      "hosted_spf_live": true,
      "delegation_missing": true
    }
  },
  "require_mfa": true
}'

Responses

200Organization

Success

Response body
idstringrequired
namestringrequired
logo_urlstring, nullablerequired
emailstring, nullablerequired
phone_numberstring, nullablerequired
websitestring, nullablerequired
is_activebooleanrequired
require_mfabooleanrequired

Whether every member must complete multi-factor authentication to sign in to this organization. A member who has not set up an authenticator is asked to at their next sign-in.

settingsobject, nullable
properties
email_notificationsobject

Email notification preferences for the organization. Controls which types of emails are sent.

properties
domain_driftedboolean

Send notifications when domain DNS records drift from expected configuration.

Default: true
domain_failedboolean

Send notifications when a domain fails DMARC validation checks.

Default: true
domain_setupboolean

Send notifications when a domain DMARC configuration is successfully set up.

Default: true
tasks_digestsboolean

Send daily digest of new and pending tasks.

Default: true
setup_remindersboolean

Send reminders to finish adding and verifying a first domain.

Default: true
first_reportboolean

Send an email when a newly set-up domain's first DMARC data arrives, and its first report a week later.

Default: true
invitation_remindersboolean

Remind invitees about an unaccepted invitation, and tell the inviter which invitations are about to expire.

Default: true
billing_noticesboolean

Send plan-usage notices, such as passing the Free plan monthly email allowance.

Default: true
hosted_spf_liveboolean

Send a one-time email when a domain's Hosted SPF setup finishes and starts serving.

Default: true
delegation_missingboolean

Send a notification when a domain never delegated to a record Palisade hosts for it, so the hosted record is not serving. Controlled separately from domain_drifted.

Default: true
onboarding_dismissed_atstring (date-time), nullable

When someone dismissed or finished the onboarding wizard for this organization. Absent or null means nobody has, and the wizard is still offered to an organization with no domains.

created_atstring (date-time)required
updated_atstring (date-time)required
support_providerSupportProviderrequired
One of: palisade, sherweb
has_domainsboolean

Delete an organization

DELETE/organizations/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/organizations/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

202object

Accepted

Response body
deletedboolean enumrequired
One of: true
objectstring enumrequired
One of: organization
idstringrequired

Dismiss onboarding

POST/organizations/{id}/onboarding/dismissrequires auth

Records that the onboarding wizard has been dismissed or finished, so it is not offered again. Idempotent: a second call keeps the first timestamp. Requires domains:read, the same permission that decides whether the wizard is shown.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/organizations/<id>/onboarding/dismiss" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200Organization

Success

Response body
idstringrequired
namestringrequired
logo_urlstring, nullablerequired
emailstring, nullablerequired
phone_numberstring, nullablerequired
websitestring, nullablerequired
is_activebooleanrequired
require_mfabooleanrequired

Whether every member must complete multi-factor authentication to sign in to this organization. A member who has not set up an authenticator is asked to at their next sign-in.

settingsobject, nullable
properties
email_notificationsobject

Email notification preferences for the organization. Controls which types of emails are sent.

properties
domain_driftedboolean

Send notifications when domain DNS records drift from expected configuration.

Default: true
domain_failedboolean

Send notifications when a domain fails DMARC validation checks.

Default: true
domain_setupboolean

Send notifications when a domain DMARC configuration is successfully set up.

Default: true
tasks_digestsboolean

Send daily digest of new and pending tasks.

Default: true
setup_remindersboolean

Send reminders to finish adding and verifying a first domain.

Default: true
first_reportboolean

Send an email when a newly set-up domain's first DMARC data arrives, and its first report a week later.

Default: true
invitation_remindersboolean

Remind invitees about an unaccepted invitation, and tell the inviter which invitations are about to expire.

Default: true
billing_noticesboolean

Send plan-usage notices, such as passing the Free plan monthly email allowance.

Default: true
hosted_spf_liveboolean

Send a one-time email when a domain's Hosted SPF setup finishes and starts serving.

Default: true
delegation_missingboolean

Send a notification when a domain never delegated to a record Palisade hosts for it, so the hosted record is not serving. Controlled separately from domain_drifted.

Default: true
onboarding_dismissed_atstring (date-time), nullable

When someone dismissed or finished the onboarding wizard for this organization. Absent or null means nobody has, and the wizard is still offered to an organization with no domains.

created_atstring (date-time)required
updated_atstring (date-time)required
support_providerSupportProviderrequired
One of: palisade, sherweb
has_domainsboolean

Usage

Get domain usage counts

GET/usagerequires auth

Query parameters

date_fromstring (date)required
date_tostring (date)required
expandarray of string enum
One of: domains, organizations, line_items, aligned_messages

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/usage" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200Usage

Success

Response body
active_domainsnumberrequired
inactive_domainsnumberrequired
parked_domainsnumberrequired
deleted_domainsnumberrequired
domainsarray of object
items
idstring (uuid)required
urlstringrequired
is_activebooleanrequired
is_parkedbooleanrequired
organization_idstring (uuid)required
organizationsarray of object
items
idstring (uuid)required
namestringrequired
active_domainsnumberrequired
inactive_domainsnumberrequired
parked_domainsnumberrequired
is_trialingbooleanrequired
line_itemsarray of LineItem
LineItem
skustring enumrequired
One of: DOMAIN-ACTIVE-TRIAL, DOMAIN-ACTIVE-FREE, DOMAIN-ACTIVE-1TO10, DOMAIN-ACTIVE-11TO100, DOMAIN-ACTIVE-101TO1000, DOMAIN-ACTIVE-1001PLUS, DOMAIN-INACTIVE, DOMAIN-PARKED, AGENT-ADDON
quantitynumberrequired
line_itemsarray of LineItem
LineItem
skustring enumrequired
One of: DOMAIN-ACTIVE-TRIAL, DOMAIN-ACTIVE-FREE, DOMAIN-ACTIVE-1TO10, DOMAIN-ACTIVE-11TO100, DOMAIN-ACTIVE-101TO1000, DOMAIN-ACTIVE-1001PLUS, DOMAIN-INACTIVE, DOMAIN-PARKED, AGENT-ADDON
quantitynumberrequired
aligned_messagesinteger

How many messages authenticated as the organization's own mail (SPF- or DKIM-aligned) were reported over the requested range, across the organization and any active children. This is the volume an IT teams tier is sold against. Returned only when requested through expand, since it aggregates the DMARC report table.

Min: 0

Member

List organization members

GET/membersrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/members" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of Memberrequired
Member
user_idstring (uuid)required
emailstring, nullablerequired
namestring, nullablerequired
picturestring (uri), nullablerequired
login_methodstring enumrequired
One of: email_password, google, microsoft
restricted_to_groupsbooleanrequired
groupsarray of string (uuid)required
rolesarray of MemberRolerequired
MemberRole
One of: admin, editor, viewer
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Add an existing account

POST/membersrequires auth

Adds an existing Palisade account to your organization. Use this when the person already has an account: POST /invitations sends them to a signup screen they cannot complete, and returns invitation_invitee_exists for such an address. Returns 201 when the account is added and 200 when it was already a member, in which case the requested roles and groups are still applied.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

emailstring (email)required

Email address of an existing Palisade account. Use POST /invitations for someone who has no account yet.

rolesarray of MemberRolerequired
MemberRole
One of: admin, editor, viewer
groupsarray of string (uuid)

Example request

curl -X POST "https://api.palisade.email/members" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "user@example.com",
  "roles": [
    "admin"
  ],
  "groups": [
    "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
  ]
}'

Responses

200Member

Already a member; roles and groups applied

Response body
user_idstring (uuid)required
emailstring, nullablerequired
namestring, nullablerequired
picturestring (uri), nullablerequired
login_methodstring enumrequired
One of: email_password, google, microsoft
restricted_to_groupsbooleanrequired
groupsarray of string (uuid)required
rolesarray of MemberRolerequired
MemberRole
One of: admin, editor, viewer
201Member

Added

Response body
user_idstring (uuid)required
emailstring, nullablerequired
namestring, nullablerequired
picturestring (uri), nullablerequired
login_methodstring enumrequired
One of: email_password, google, microsoft
restricted_to_groupsbooleanrequired
groupsarray of string (uuid)required
rolesarray of MemberRolerequired
MemberRole
One of: admin, editor, viewer
400MemberAccountNotFound

No Palisade account exists for this email address. Send an invitation instead.

Response body
codestring enumrequired
One of: parameter_invalid_or_missing
paramstring enumrequired
One of: email
messagestringrequired

Update a member

POST/members/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

rolesarray of MemberRole
MemberRole
One of: admin, editor, viewer
groupsarray of string (uuid)

Example request

curl -X POST "https://api.palisade.email/members/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "roles": [
    "admin"
  ],
  "groups": [
    "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
  ]
}'

Responses

200Member

Success

Response body
user_idstring (uuid)required
emailstring, nullablerequired
namestring, nullablerequired
picturestring (uri), nullablerequired
login_methodstring enumrequired
One of: email_password, google, microsoft
restricted_to_groupsbooleanrequired
groupsarray of string (uuid)required
rolesarray of MemberRolerequired
MemberRole
One of: admin, editor, viewer

Remove a member

DELETE/members/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/members/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Deleted

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

List member MFA statuses

GET/members/mfa/statusesrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/members/mfa/statuses" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200GetMembersMfaStatusesResponse

Success

Response body
statusesobjectrequired

MtaSts

Get MTA-STS status

GET/domains/{domainId}/mta-stsrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/mta-sts" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200MtaSts

Success

Response body
is_managedbooleanrequired
statusDnsStatus & object, nullablerequired
modestring enum, nullablerequired
One of: testing, enforce, none
max_agenumber, nullablerequired
mxarray of stringrequired
policy_idstring, nullablerequired
custom_hostname_idstring, nullablerequired
cname_targetstringrequired
txt_cname_targetstringrequired
tls_reporting_emailstring, nullablerequired
tls_rpt_recordstring, nullablerequired

Enable MTA-STS

POST/domains/{domainId}/mta-stsrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

modestring enum
One of: testing, enforce, none · Default: "testing"
max_agenumber
Default: 86400 · Min: 86400 · Max: 31557600

Example request

curl -X POST "https://api.palisade.email/domains/<domainId>/mta-sts" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

200MtaSts

Success

Response body
is_managedbooleanrequired
statusDnsStatus & object, nullablerequired
modestring enum, nullablerequired
One of: testing, enforce, none
max_agenumber, nullablerequired
mxarray of stringrequired
policy_idstring, nullablerequired
custom_hostname_idstring, nullablerequired
cname_targetstringrequired
txt_cname_targetstringrequired
tls_reporting_emailstring, nullablerequired
tls_rpt_recordstring, nullablerequired

Update the MTA-STS policy

PUT/domains/{domainId}/mta-stsrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

modestring enum
One of: testing, enforce, none
max_agenumber
Min: 86400 · Max: 31557600

Example request

curl -X PUT "https://api.palisade.email/domains/<domainId>/mta-sts" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "mode": "testing",
  "max_age": 86400
}'

Responses

200MtaSts

Success

Response body
is_managedbooleanrequired
statusDnsStatus & object, nullablerequired
modestring enum, nullablerequired
One of: testing, enforce, none
max_agenumber, nullablerequired
mxarray of stringrequired
policy_idstring, nullablerequired
custom_hostname_idstring, nullablerequired
cname_targetstringrequired
txt_cname_targetstringrequired
tls_reporting_emailstring, nullablerequired
tls_rpt_recordstring, nullablerequired

Disable MTA-STS

DELETE/domains/{domainId}/mta-stsrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/domains/<domainId>/mta-sts" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200MtaSts

Success

Response body
is_managedbooleanrequired
statusDnsStatus & object, nullablerequired
modestring enum, nullablerequired
One of: testing, enforce, none
max_agenumber, nullablerequired
mxarray of stringrequired
policy_idstring, nullablerequired
custom_hostname_idstring, nullablerequired
cname_targetstringrequired
txt_cname_targetstringrequired
tls_reporting_emailstring, nullablerequired
tls_rpt_recordstring, nullablerequired

Retry a failed MTA-STS setup

POST/domains/{domainId}/mta-sts/retryrequires auth

Requests a fresh certificate for mta-sts.{domain} after a failed setup. The domain must already have MTA-STS hosting enabled, must currently be in the error state, and must be publishing the mta-sts CNAME, otherwise the retry is refused with an explanation. A setup still in progress is refused rather than restarted. Returns the domain unchanged when its certificate is already active.

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/domains/<domainId>/mta-sts/retry" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200MtaSts

Success

Response body
is_managedbooleanrequired
statusDnsStatus & object, nullablerequired
modestring enum, nullablerequired
One of: testing, enforce, none
max_agenumber, nullablerequired
mxarray of stringrequired
policy_idstring, nullablerequired
custom_hostname_idstring, nullablerequired
cname_targetstringrequired
txt_cname_targetstringrequired
tls_reporting_emailstring, nullablerequired
tls_rpt_recordstring, nullablerequired

Report Data

Get the report summary

GET/report-data/summaryrequires auth

Query parameters

periodstring enum
One of: last_1_day, last_7_days, last_30_days, last_365_days
date_fromstring
date_tostring

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/report-data/summary" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ReportSummary

Success

Response body
date_fromstringrequired
date_tostringrequired
total_domainsintegerrequired
managed_domainsintegerrequired
monitored_domainsintegerrequired
avg_last_14_days_pass_ratenumberrequired
sendersarray of ReportSenderVolumerequired
ReportSenderVolume
namestringrequired
volume_passintegerrequired
volume_failintegerrequired

List domain report scores

GET/report-data/domainsrequires auth

Query parameters

periodstring enum
One of: last_1_day, last_7_days, last_30_days, last_365_days
date_fromstring
date_tostring
pagenumber
per_pagenumber
group_idstring (uuid)

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/report-data/domains" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of ReportDomainrequired
ReportDomain
idstring (uuid)required
urlstringrequired
scoreintegerrequired
score_bandstring enumrequired
One of: critical, bad, good, great
policystringrequired
is_dmarc_managedbooleanrequired
last_14_days_volumeintegerrequired
last_14_days_pass_rate_dmarcnumberrequired
last_14_days_pass_rate_spfnumberrequired
last_14_days_pass_rate_dkimnumberrequired
threats_countintegerrequired
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

List senders for a domain

GET/report-data/domains/{domainId}/sendersrequires auth

Path parameters

domainIdstring (uuid)required

Query parameters

periodstring enum
One of: last_1_day, last_7_days, last_30_days, last_365_days
date_fromstring
date_tostring

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/report-data/domains/<domainId>/senders" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ReportDomainSenders

Success

Response body
date_fromstringrequired
date_tostringrequired
sendersarray of ReportSenderAggregaterequired
ReportSenderAggregate
namestringrequired
message_countintegerrequired
dmarc_passedintegerrequired
dmarc_failedintegerrequired
spf_passedintegerrequired
dkim_passedintegerrequired

Get daily volume

GET/report-data/domains/{domainId}/timeseriesrequires auth

Path parameters

domainIdstring (uuid)required

Query parameters

periodstring enum
One of: last_1_day, last_7_days, last_30_days, last_365_days
date_fromstring
date_tostring

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/report-data/domains/<domainId>/timeseries" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ReportDomainTimeseries

Success

Response body
date_fromstringrequired
date_tostringrequired
seriesarray of ReportTimeseriesPointrequired
ReportTimeseriesPoint
datestringrequired
message_countintegerrequired
compliantintegerrequired
non_compliantintegerrequired
forwardedintegerrequired
unknownintegerrequired
undeterminedintegerrequired

Prospecting Reports

Download the hosted PDF

GET/prospecting-reports/{id}/download

Serves the report to anyone holding the link — no authentication, since the recipient is a prospect. Reports are available for 90 days from creation; after that this returns 410 with a page explaining that the report expired, or the JSON below when the request asks for it.

Path parameters

idstring (uuid)required

Example request

curl "https://api.palisade.email/prospecting-reports/<id>/download"

Responses

200string (binary)

The report as a PDF

Response body
string (binary)
410ProspectingReportGone

The report has expired and is no longer available

Response body
codestring enumrequired
One of: prospecting_report_expired
messagestringrequired
expires_atstring (date-time)required

List prospecting reports

GET/prospecting-reportsrequires auth

Prospecting reports created through this API, newest first. API keys see every one in the organization. A member limited to groups sees only the reports they created and the reports whose domains are all monitored domains in their groups.

Query parameters

pagenumber
per_pagenumber

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/prospecting-reports" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of ProspectingReportrequired
ProspectingReport
idstring (uuid)required
generated_forstringrequired
Min length: 1
languagestring enumrequired
One of: en, fr
requested_bystringrequired
Min length: 1
domainsarray of stringrequired
include_organization_infobooleanrequired
include_bimibooleanrequired
include_dns_recordsbooleanrequired
include_potential_lossbooleanrequired
themestring enumrequired

The skin the report is drawn in: light on paper, or dark on a near-black ground.

One of: light, dark
currencystring enumrequired

The currency every price band in the report is printed in.

One of: USD, CAD, EUR, GBP, AUD
deadline_weeksintegerrequired

How many weeks the plan and closing pages give the reader to fix what the report found.

Min: 1 · Max: 52
urlstring (uri)required
expires_atstring (date-time)required
expiredbooleanrequired
created_atstring (date-time)required
updated_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Generate a prospecting report

POST/prospecting-reportsrequires auth

Audits each domain against live DNS, renders the email security report as a PDF, and hosts it. The domains are looked up publicly and do not need to be in your account, which is what makes this usable on a prospect. Up to 10 domains per report. The response carries a url anyone with the link can open, good for 90 days; delete the report to stop it resolving sooner.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

generated_forstringrequired
Min length: 1
domainsarray of stringrequired
languagestring enum
One of: en, fr · Default: "en"
include_organization_infoboolean
Default: true
include_bimiboolean
Default: true
include_dns_recordsboolean
Default: false
include_potential_lossboolean
Default: true
themestring enum

The skin the report is drawn in: light on paper, or dark on a near-black ground.

One of: light, dark · Default: "light"
currencystring enum

The currency every price band in the report is printed in.

One of: USD, CAD, EUR, GBP, AUD · Default: "USD"
deadline_weeksinteger

How many weeks the plan and closing pages give the reader to fix what the report found.

Default: 6 · Min: 1 · Max: 52

Example request

curl -X POST "https://api.palisade.email/prospecting-reports" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "generated_for": "string",
  "domains": [
    "string"
  ],
  "language": "en",
  "include_organization_info": true,
  "include_bimi": true,
  "include_dns_records": false,
  "include_potential_loss": true,
  "theme": "light",
  "currency": "USD",
  "deadline_weeks": 6
}'

Responses

201ProspectingReport

Created

Response body
idstring (uuid)required
generated_forstringrequired
Min length: 1
languagestring enumrequired
One of: en, fr
requested_bystringrequired
Min length: 1
domainsarray of stringrequired
include_organization_infobooleanrequired
include_bimibooleanrequired
include_dns_recordsbooleanrequired
include_potential_lossbooleanrequired
themestring enumrequired

The skin the report is drawn in: light on paper, or dark on a near-black ground.

One of: light, dark
currencystring enumrequired

The currency every price band in the report is printed in.

One of: USD, CAD, EUR, GBP, AUD
deadline_weeksintegerrequired

How many weeks the plan and closing pages give the reader to fix what the report found.

Min: 1 · Max: 52
urlstring (uri)required
expires_atstring (date-time)required
expiredbooleanrequired
created_atstring (date-time)required
updated_atstring (date-time)required

Preview a report

POST/prospecting-reports/previewrequires auth

Runs the same audit as POST /prospecting-reports and returns the report itself rather than a link to a hosted PDF. format: "json" returns the report as data -- every score, finding and figure the PDF prints, with the wording resolved for the requested language -- so you can render it in your own layout. format: "html" returns the same report as a complete, self-contained HTML document, styled by Palisade and carrying your organization's name, logo and contact details. Nothing is stored and no link is minted, so use this for a page rendered on demand and POST /prospecting-reports when the recipient needs a PDF they can keep.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

generated_forstringrequired
Min length: 1
domainsarray of stringrequired
languagestring enum
One of: en, fr · Default: "en"
include_organization_infoboolean
Default: true
include_bimiboolean
Default: true
include_dns_recordsboolean
Default: false
include_potential_lossboolean
Default: true
themestring enum

The skin the report is drawn in: light on paper, or dark on a near-black ground.

One of: light, dark · Default: "light"
currencystring enum

The currency every price band in the report is printed in.

One of: USD, CAD, EUR, GBP, AUD · Default: "USD"
deadline_weeksinteger

How many weeks the plan and closing pages give the reader to fix what the report found.

Default: 6 · Min: 1 · Max: 52
formatstring enum

json returns the report as data; html returns the same report as a complete, self-contained HTML document.

One of: json, html · Default: "json"

Example request

curl -X POST "https://api.palisade.email/prospecting-reports/preview" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "generated_for": "string",
  "domains": [
    "string"
  ],
  "language": "en",
  "include_organization_info": true,
  "include_bimi": true,
  "include_dns_records": false,
  "include_potential_loss": true,
  "theme": "light",
  "currency": "USD",
  "deadline_weeks": 6,
  "format": "json"
}'

Responses

200ProspectingReportContent

The report as data, or as an HTML document when format is "html"

Response body
languagestring enumrequired
One of: en, fr
themestring enumrequired

The skin the report is drawn in: light on paper, or dark on a near-black ground.

One of: light, dark
currencystring enumrequired

The currency every price band in the report is printed in.

One of: USD, CAD, EUR, GBP, AUD
deadline_weeksintegerrequired

How many weeks the plan and closing pages give the reader to fix what the report found.

Min: 1 · Max: 52
generated_atstring (date-time)required
generated_bystringrequired

Your organization name, as the report signs itself.

generated_forstringrequired
organization_logostring, nullablerequired
contact_infoobjectrequired
properties
emailstringrequired
phonestringrequired
websitestringrequired
optionsobjectrequired
properties
include_bimibooleanrequired
include_dns_recordsbooleanrequired
include_potential_lossbooleanrequired
coverProspectingReportCoverrequired
ProspectingReportCover
yearintegerrequired
domains_analyzedstringrequired
datestringrequired

The generated date as the report prints it, in the requested language.

verdict_keystring enumrequired
One of: one, some, all, partial_one, partial, none
verdictstringrequired
verdict_detailstringrequired
high_risk_findingsintegerrequired
medium_findingsintegerrequired
exposed_domainsintegerrequired
protected_domainsintegerrequired
high_risk_labelstring, nullablerequired
medium_labelstring, nullablerequired
protected_labelstring, nullablerequired
rowsarray of ProspectingReportCoverRowrequired

Worst score first, capped at the number of rows the cover prints.

ProspectingReportCoverRow
urlstringrequired
logostring, nullablerequired
scoreintegerrequired
score_bandstring enumrequired
One of: critical, bad, good, great
risk_levelstring enumrequired
One of: critical, high, medium, low
is_exposedbooleanrequired
is_fully_protectedbooleanrequired
findingsintegerrequired

How many of the domain's checks are issues rather than passes.

findings_labelstringrequired
score_labelstringrequired
chipobjectrequired
properties
typestring enumrequired
One of: pass, fail, soft-warn, info
labelstring, nullablerequired
more_domainsstring, nullablerequired

Set when the report holds more domains than the cover lists.

domainsarray of ProspectingReportDomainrequired
ProspectingReportDomain
urlstringrequired
scoreintegerrequired
score_bandstring enumrequired
One of: critical, bad, good, great
risk_levelstring enumrequired
One of: critical, high, medium, low
risk_level_labelstring, nullablerequired
percentilenumberrequired

Deprecated. A value read off a fixed curve, not a comparison with the scores of other domains, so it does not say how this domain ranks. The report stopped printing it for that reason; it is kept only so existing callers do not break. Do not show it to a reader as a ranking.

logostring, nullablerequired
dmarcobjectrequired
properties
policystringrequired

none, quarantine, reject, or unknown when the domain publishes no DMARC record.

pctnumber, nullablerequired
spoofing_riskstring enumrequired
One of: high, medium, low, unknown
spoofing_risk_labelstring, nullablerequired
is_fully_protectedbooleanrequired

True only at reject with pct=100.

risk_summaryProspectingReportRiskSummaryrequired
ProspectingReportRiskSummary
high_risk_itemsintegerrequired
medium_risk_itemsintegerrequired
by_categoryobjectrequired
properties
securityobjectrequired
properties
highintegerrequired
mediumintegerrequired
deliverabilityobjectrequired
properties
highintegerrequired
mediumintegerrequired
findingsarray of ProspectingReportFindingrequired

Every check, including the ones that pass.

ProspectingReportFinding
keystringrequired

Which check this is: mx, spf, dmarc, bimi.

statusstringrequired

pass, warn, fail or error.

status_labelstring, nullablerequired

The risk word the report prints for this status, in language.

risk_categorystring, nullablerequired

security or deliverability.

risk_category_labelstring, nullablerequired
messagestring, nullablerequired

The finding as the report states it, in language.

potential_lossProspectingReportPotentialLossrequired

Null when include_potential_loss is false.

ProspectingReportPotentialLoss
revenue_loss_pctnumberrequired
revenue_loss_displaystringrequired

The figure as the report prints it, which floors a perfect score at "<10%".

financial_lossnumberrequired
financial_loss_displaystringrequired
dns_recordsobject, nullablerequired

The records as published. Null unless include_dns_records is true.

properties
dmarcarray of stringrequired
spfarray of stringrequired
mxarray of stringrequired
bimiarray of stringrequired
sendersarray of objectrequired

The services the domain's SPF record authorises to send as it. Empty when it publishes none.

items
namestringrequired

The catalogue's name for the service, or the SPF host itself when the catalogue has no entry.

includestringrequired

The host as it stands in the domain's own SPF record.

logostring, nullablerequired
dkimstring enumrequired

Whether a DKIM key for this service was found on the domain. unknown when the service publishes per-customer selectors, which cannot be enumerated, or when it publishes none the check knows.

One of: signed, missing, unknown
mail_kindstring enum, nullablerequired

What kind of mail the service carries for the domain, from the curated catalogue. Null when unknown.

One of: invoices, marketing, sales, support, notifications, transactional, payroll, mailbox, security-gateway, relay
domains_without_auditarray of stringrequired

Domains whose nameservers returned nothing usable, so the report has no page for them.

Get a prospecting report

GET/prospecting-reports/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/prospecting-reports/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ProspectingReport

Success

Response body
idstring (uuid)required
generated_forstringrequired
Min length: 1
languagestring enumrequired
One of: en, fr
requested_bystringrequired
Min length: 1
domainsarray of stringrequired
include_organization_infobooleanrequired
include_bimibooleanrequired
include_dns_recordsbooleanrequired
include_potential_lossbooleanrequired
themestring enumrequired

The skin the report is drawn in: light on paper, or dark on a near-black ground.

One of: light, dark
currencystring enumrequired

The currency every price band in the report is printed in.

One of: USD, CAD, EUR, GBP, AUD
deadline_weeksintegerrequired

How many weeks the plan and closing pages give the reader to fix what the report found.

Min: 1 · Max: 52
urlstring (uri)required
expires_atstring (date-time)required
expiredbooleanrequired
created_atstring (date-time)required
updated_atstring (date-time)required

Delete a prospecting report

DELETE/prospecting-reports/{id}requires auth

Deletes the report and the hosted PDF, so any link already sent out stops resolving.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/prospecting-reports/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

Scheduled Reports

List scheduled reports

GET/scheduled-reportsrequires auth

Query parameters

pagenumber
per_pagenumber
customer_namestring

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/scheduled-reports" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of ScheduledReportrequired
ScheduledReport
idstring (uuid)required
customer_namestringrequired
Min length: 1
domain_idsarray of string (uuid)required
schedule_frequencystringrequired
Min length: 1
auto_sendbooleanrequired
email_recipientsarray of string (email)
Default: []
generated_atstring (date-time), nullablerequired
created_bystringrequired
Min length: 1
created_atstring (date-time)required
updated_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Create a scheduled report

POST/scheduled-reportsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

customer_namestringrequired
Min length: 1
domain_idsarray of string (uuid)required
schedule_frequencystring
Default: "0 0 1 * *" · Min length: 1
auto_sendboolean
Default: false
email_recipientsarray of string (email)
Default: []

Example request

curl -X POST "https://api.palisade.email/scheduled-reports" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "customer_name": "string",
  "domain_ids": [
    "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
  ],
  "schedule_frequency": "0 0 1 * *",
  "auto_send": false,
  "email_recipients": []
}'

Responses

201ScheduledReport

Success

Response body
idstring (uuid)required
customer_namestringrequired
Min length: 1
domain_idsarray of string (uuid)required
schedule_frequencystringrequired
Min length: 1
auto_sendbooleanrequired
email_recipientsarray of string (email)
Default: []
generated_atstring (date-time), nullablerequired
created_bystringrequired
Min length: 1
created_atstring (date-time)required
updated_atstring (date-time)required

Get a scheduled report

GET/scheduled-reports/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/scheduled-reports/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ScheduledReport

Success

Response body
idstring (uuid)required
customer_namestringrequired
Min length: 1
domain_idsarray of string (uuid)required
schedule_frequencystringrequired
Min length: 1
auto_sendbooleanrequired
email_recipientsarray of string (email)
Default: []
generated_atstring (date-time), nullablerequired
created_bystringrequired
Min length: 1
created_atstring (date-time)required
updated_atstring (date-time)required

Update a scheduled report

POST/scheduled-reports/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

customer_namestring
Min length: 1
domain_idsarray of string (uuid)
schedule_frequencystring
Min length: 1
auto_sendboolean
email_recipientsarray of string (email)
generated_atstring (date-time), nullable

Example request

curl -X POST "https://api.palisade.email/scheduled-reports/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "customer_name": "string",
  "domain_ids": [
    "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
  ],
  "schedule_frequency": "string",
  "auto_send": true,
  "email_recipients": [
    "user@example.com"
  ],
  "generated_at": "2025-01-15T12:00:00.000Z"
}'

Responses

200ScheduledReport

Success

Response body
idstring (uuid)required
customer_namestringrequired
Min length: 1
domain_idsarray of string (uuid)required
schedule_frequencystringrequired
Min length: 1
auto_sendbooleanrequired
email_recipientsarray of string (email)
Default: []
generated_atstring (date-time), nullablerequired
created_bystringrequired
Min length: 1
created_atstring (date-time)required
updated_atstring (date-time)required

Delete a scheduled report

DELETE/scheduled-reports/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/scheduled-reports/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Deleted

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

SupportRequest

Send a support request

POST/support-requestsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

contentstringrequired
Min length: 1 · Max length: 4000
titlestringrequired
Min length: 1 · Max length: 100

Example request

curl -X POST "https://api.palisade.email/support-requests" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "string",
  "title": "string"
}'

Responses

200object

Success

Response body
statusstring enumrequired
One of: created

SupportTicket

List support tickets

GET/support/ticketsrequires auth

Returns paginated list of support tickets. Admins see all org tickets; other roles see only their own tickets. Filter by status or priority using query params.

Query parameters

statusarray of SupportTicketStatus
One of: open, pending_customer, pending_support, resolved, closed
priorityarray of SupportTicketPriority
One of: low, normal, high, urgent, critical
per_pagenumber
pagenumber

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/support/tickets" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of SupportTicketrequired
SupportTicket
idstring (uuid)required
ticket_idstring, nullablerequired
subjectstringrequired
statusSupportTicketStatusrequired
One of: open, pending_customer, pending_support, resolved, closed
prioritySupportTicketPriorityrequired
One of: low, normal, high, urgent, critical
hostname_urlstring, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
last_message_atstring (date-time), nullablerequired
unread_countnumberrequired
organization_namestring, nullable
created_by_namestring, nullable
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Open a support ticket

POST/support/ticketsrequires auth

Creates a new support ticket with an initial message. Optionally link to a hostname or task. Returns the created ticket ID.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

subjectstringrequired
Min length: 1 · Max length: 255
contentstringrequired
Min length: 1
prioritySupportTicketPriority & object
hostname_idstring (uuid)
attachmentsarray of object
items
file_namestringrequired
file_urlstring (uri)required
file_sizenumber, nullable
mime_typestring, nullable
attachment_typeSupportTicketAttachmentTyperequired
One of: file, link

Example request

curl -X POST "https://api.palisade.email/support/tickets" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "subject": "string",
  "content": "string",
  "priority": {},
  "hostname_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1",
  "attachments": [
    {
      "file_name": "string",
      "file_url": "https://example.com",
      "file_size": 0,
      "mime_type": "string",
      "attachment_type": "file"
    }
  ]
}'

Responses

201object

Created

Response body
dataobjectrequired
properties
idstring (uuid)required

Get a support ticket

GET/support/tickets/{id}requires auth

Returns a single ticket with its full message thread. Messages are ordered chronologically. Marks all support messages as read for the requesting user.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/support/tickets/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200SupportTicketDetail

Success

Response body
idstring (uuid)required
ticket_idstring, nullablerequired
subjectstringrequired
statusSupportTicketStatusrequired
One of: open, pending_customer, pending_support, resolved, closed
prioritySupportTicketPriorityrequired
One of: low, normal, high, urgent, critical
hostname_idstring, nullablerequired
hostname_urlstring, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
resolved_atstring (date-time), nullablerequired
messagesarray of SupportTicketMessagerequired
SupportTicketMessage
idstring (uuid)required
author_idstringrequired
author_typeSupportTicketAuthorTyperequired
One of: customer, support, system
author_namestring, nullablerequired
author_emailstring, nullablerequired
contentstringrequired
is_ai_draftbooleanrequired
created_atstring (date-time)required
read_atstring (date-time), nullablerequired
attachmentsarray of SupportTicketAttachmentrequired
SupportTicketAttachment
idstring (uuid)required
file_namestringrequired
file_urlstringrequired

Download URL for the attachment. For uploaded files this is a signed URL minted for this response and valid for one hour; fetch the ticket again for a fresh one rather than storing it. For link attachments it is the URL as supplied.

file_sizenumber, nullablerequired
mime_typestring, nullablerequired
attachment_typeSupportTicketAttachmentTyperequired
One of: file, link
created_atstring (date-time)required
organization_namestring, nullable

Close or reopen a ticket

PATCH/support/tickets/{id}requires auth

Updates ticket status. Users can close a resolved ticket or reopen a closed/resolved ticket.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

statusAllowedUserStatusUpdaterequired
One of: open, closed

Example request

curl -X PATCH "https://api.palisade.email/support/tickets/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "open"
}'

Responses

200object

Success

Response body
idstring (uuid)required
statusSupportTicketStatusrequired
One of: open, pending_customer, pending_support, resolved, closed

Reply to a ticket

POST/support/tickets/{id}/messagesrequires auth

Adds a reply message to an existing ticket. Updates ticket status to PENDING_SUPPORT.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

contentstringrequired
Min length: 1
attachmentsarray of object
items
file_namestringrequired
file_urlstring (uri)required
file_sizenumber, nullable
mime_typestring, nullable
attachment_typeSupportTicketAttachmentTyperequired
One of: file, link

Example request

curl -X POST "https://api.palisade.email/support/tickets/<id>/messages" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "content": "string",
  "attachments": [
    {
      "file_name": "string",
      "file_url": "https://example.com",
      "file_size": 0,
      "mime_type": "string",
      "attachment_type": "file"
    }
  ]
}'

Responses

201object

Created

Response body
idstring (uuid)required

Get the unread count

GET/support/unread-countrequires auth

Returns the count of unread support messages across visible tickets. Lightweight query for badge polling.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/support/unread-count" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
countnumberrequired

Get an attachment upload URL

POST/support/presigned-urlrequires auth

Generates a presigned URL for uploading support ticket attachments to S3. Supports images and PDFs up to 10MB.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

file_namestringrequired
Min length: 1 · Max length: 255
mime_typeSupportAttachmentMimeTyperequired
One of: image/png, image/jpeg, image/gif, image/webp, application/pdf

Example request

curl -X POST "https://api.palisade.email/support/presigned-url" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "file_name": "string",
  "mime_type": "image/png"
}'

Responses

200object

Success

Response body
presigned_urlstring (uri)required
public_urlstring (uri)required

TlsReport

List TLS-RPT reports

GET/domains/{domainId}/tls-reportsrequires auth

List the TLS-RPT reports sending servers have submitted for this domain. Reports only arrive once the domain publishes an MTA-STS policy and a TLS-RPT record.

Path parameters

domainIdstring (uuid)required

Query parameters

pagenumber
per_pagenumber
date_fromstring (date)
date_tostring (date)
sort_bystring enum
One of: day, total_successful, total_failure, organization_name
sort_orderstring enum
One of: desc, asc

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/tls-reports" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of objectrequired
items
idstringrequired
hostname_idstringrequired
report_idstringrequired
organization_namestringrequired
contact_infostring, nullablerequired
date_range_startstringrequired
date_range_endstringrequired
daystringrequired
policy_typestringrequired
policy_domainstringrequired
mx_hoststring, nullablerequired
total_successfulnumberrequired
total_failurenumberrequired
created_atstringrequired
failuresarray of objectrequired
items
result_typestringrequired
sending_mta_ipstring, nullablerequired
receiving_ipstring, nullablerequired
receiving_mx_hostnamestring, nullablerequired
failed_session_countnumberrequired
additional_infostring, nullablerequired
failure_reason_codestring, nullablerequired
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Get daily TLS session counts

GET/domains/{domainId}/tls-reports/chartrequires auth

Successful and failed TLS session counts per day over the requested window, as parallel arrays aligned to labels.

Path parameters

domainIdstring (uuid)required

Query parameters

date_fromstring (date)required
date_tostring (date)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/tls-reports/chart" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
labelsarray of stringrequired
successfularray of numberrequired
failurearray of numberrequired
totalsobjectrequired
properties
successfulnumberrequired
failurenumberrequired

Get the TLS-RPT summary

GET/domains/{domainId}/tls-reports/summaryrequires auth

Aggregate TLS session totals for the requested window, with failures broken down by RFC 8460 result type.

Path parameters

domainIdstring (uuid)required

Query parameters

date_fromstring (date)required
date_tostring (date)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/tls-reports/summary" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
total_successfulnumberrequired
total_failurenumberrequired
total_reportsnumberrequired
failure_breakdownarray of objectrequired
items
result_typestringrequired
countnumberrequired

Get a TLS-RPT report

GET/domains/{domainId}/tls-reports/{id}requires auth

Retrieve a single TLS-RPT report, including the per-failure detail sending servers reported.

Path parameters

domainIdstring (uuid)required
idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/tls-reports/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
idstringrequired
hostname_idstringrequired
report_idstringrequired
organization_namestringrequired
contact_infostring, nullablerequired
date_range_startstringrequired
date_range_endstringrequired
daystringrequired
policy_typestringrequired
policy_domainstringrequired
mx_hoststring, nullablerequired
total_successfulnumberrequired
total_failurenumberrequired
created_atstringrequired
failuresarray of objectrequired
items
result_typestringrequired
sending_mta_ipstring, nullablerequired
receiving_ipstring, nullablerequired
receiving_mx_hostnamestring, nullablerequired
failed_session_countnumberrequired
additional_infostring, nullablerequired
failure_reason_codestring, nullablerequired

Activity Log

List activity log entries

GET/activity-logrequires auth

Query parameters

actor_idstring
actor_emailstring
resource_typestring
resource_idstring
actionstring
date_fromstring (date-time)
date_tostring (date-time)
cursorstring
per_pagenumber

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/activity-log" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ActivityLogList

Success

Response body
dataarray of ActivityLogEntryrequired
ActivityLogEntry
idstring (uuid)required
actor_typeActivityActorTyperequired
One of: USER, API_KEY, PALISADE_STAFF, SYSTEM
actor_idstringrequired
actor_emailstring, nullablerequired
actor_namestring, nullablerequired
actor_api_key_reminderstring, nullablerequired
actionstringrequired
resource_typestring, nullablerequired
resource_idstring, nullablerequired
resource_labelstring, nullablerequired
methodstringrequired
pathstringrequired
status_codenumberrequired
request_idstring, nullablerequired
metadataobject, nullablerequired
created_atstring (date-time)required
page_infoobjectrequired
properties
has_morebooleanrequired
next_cursorstring, nullablerequired
per_pagenumberrequired

List action types

GET/activity-log/actionsrequires auth

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/activity-log/actions" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ActivityLogActions

Success

Response body
actionsarray of stringrequired

Get an activity log entry

GET/activity-log/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/activity-log/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ActivityLogEntry

Success

Response body
idstring (uuid)required
actor_typeActivityActorTyperequired
One of: USER, API_KEY, PALISADE_STAFF, SYSTEM
actor_idstringrequired
actor_emailstring, nullablerequired
actor_namestring, nullablerequired
actor_api_key_reminderstring, nullablerequired
actionstringrequired
resource_typestring, nullablerequired
resource_idstring, nullablerequired
resource_labelstring, nullablerequired
methodstringrequired
pathstringrequired
status_codenumberrequired
request_idstring, nullablerequired
metadataobject, nullablerequired
created_atstring (date-time)required

Signup

Start a headless signup

POST/signup

Start a headless signup: sends a 6-digit verification code to the given work email. No account is created until the code is verified.

Request body

emailstring (email)required

Email address that will own the new account. A verification code is sent to this inbox; the address becomes the organization admin.

organization_namestringrequired
Min length: 3 · Max length: 128
pricing_typestring enum

Self-serve plan to provision. Only honored when PLG is enabled; otherwise the default plan is used.

One of: free, it_teams, msp
attribution_idstring (uuid)

Opaque first-party journey id from palisade.email. Used only for acquisition attribution.

Example request

curl -X POST "https://api.palisade.email/signup" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "user@example.com",
  "organization_name": "string",
  "pricing_type": "free",
  "attribution_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1"
}'

Responses

202object

Verification code sent

Response body
signup_idstring (uuid)required
expires_in_secondsintegerrequired

Verify a signup code

POST/signup/verify

Verify the emailed code. On success, creates the Auth0 user (email verified), the organization, and returns an org-scoped API key exactly once.

Request body

signup_idstring (uuid)required
codestringrequired

Example request

curl -X POST "https://api.palisade.email/signup/verify" \
  -H "Content-Type: application/json" \
  -d '{
  "signup_id": "5cf10a30-0b0c-4e05-9e68-6cbfd7d3c2a1",
  "code": "string"
}'

Responses

200object

Account created

Response body
api_keystringrequired

Org-scoped API key. Shown exactly once — store it securely.

organization_idstring (uuid)required
organization_reference_idstringrequired
emailstring (email)required
next_stepsstringrequired

Source

List sending sources

GET/sourcesrequires auth

List the sending sources Palisade knows about, with the SPF and DKIM support details used to build setup instructions. Authentication is optional. instructions_curation holds unreviewed AI proposals and is null unless the caller holds sources:update.

Query parameters

statusstring enum
One of: ACTIVE, PENDING_REVIEW, REJECTED
originstring enum
One of: DMARC_IO, AI_DISCOVERED, MANUAL
searchstring

Example request

curl "https://api.palisade.email/sources" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of objectrequired
items
idstring (uuid)required
external_idstringrequired
namestringrequired
homepagestring (uri), nullablerequired
base_domainsarray of stringrequired
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
dmarc_supportbooleanrequired
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
valuestring
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
parent_source_idstring (uuid), nullable
display_namestring, nullable
envelope_fromsarray of stringrequired
is_custombooleanrequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
spf_reply_to_targetstring, nullablerequired
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
dkim_discovery_selectorsarray of stringrequired
spf_discovery_valuesarray of stringrequired
spf_reply_to_discovery_valuesarray of stringrequired
mx_domainsarray of stringrequired
dkim_instructionsobject, nullablerequired
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
spf_instructionsobject, nullable
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
namestring
valuestring
instructions_curationobject, nullable
properties
dkimobject, nullable
properties
statusstring enumrequired
One of: PENDING, APPROVED, REJECTED
proposalobjectrequired
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
namestring
valuestring
provenanceobjectrequired
properties
doc_urlstringrequired
doc_titlestring, nullablerequired
doc_discoveredbooleanrequired
modelstringrequired
confidencenumberrequired
critic_notesarray of stringrequired
generated_atstringrequired
reviewed_atstring, nullable
reviewed_bystring, nullable
spfobject, nullable
properties
statusstring enumrequired
One of: PENDING, APPROVED, REJECTED
proposalobjectrequired
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
namestring
valuestring
provenanceobjectrequired
properties
doc_urlstringrequired
doc_titlestring, nullablerequired
doc_discoveredbooleanrequired
modelstringrequired
confidencenumberrequired
critic_notesarray of stringrequired
generated_atstringrequired
reviewed_atstring, nullable
reviewed_bystring, nullable
statusstring enumrequired
One of: ACTIVE, PENDING_REVIEW, REJECTED
originstring enumrequired
One of: DMARC_IO, AI_DISCOVERED, MANUAL
ai_confidencenumber, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Get the SPF include index

GET/sources/spf-indexrequires auth

The compact include-to-sender index used to name the mechanisms in an SPF record, and to offer senders to add. Only sources that carry at least one SPF value appear. values holds the mechanisms Palisade prescribes adding; recognition_values additionally holds observed values, which name a mechanism already present in a record but are not safe to publish on a user's behalf. Authentication is optional, as on the list endpoint.

Example request

curl "https://api.palisade.email/sources/spf-index" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of objectrequired
items
idstring (uuid)required
namestringrequired
logo_urlstring, nullablerequired
homepagestring (uri), nullablerequired
valuesarray of stringrequired

SPF mechanisms Palisade prescribes adding for this source. Safe to publish on a user's behalf.

recognition_valuesarray of stringrequired

Every mechanism that identifies this source, including values only observed in the wild. Use these to name a mechanism already present in a record; they are not safe to add to one.

requires_advanced_configbooleanrequired

When true, the mechanism depends on per-customer setup and must not be offered as a one-click add.

page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Get the DKIM selector index

GET/sources/dkim-indexrequires auth

The compact index used to name the DKIM keys already published for a domain. A key is matched either by selectors, the selector conventions a source publishes under, or by base_domains, the zones its CNAME targets sit in — the latter being the only signal that identifies a per-customer selector such as HubSpot's hs1-<portalId>. Only sources carrying at least one of the two appear. Authentication is optional, as on the list endpoint.

Example request

curl "https://api.palisade.email/sources/dkim-index" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of objectrequired
items
idstring (uuid)required
namestringrequired
logo_urlstring, nullablerequired
homepagestring, nullablerequired

The source's home page. Free text on the record rather than a validated URL - a handful of sources carry a bare hostname such as samanage.com - so treat it as a hostname that may or may not carry a scheme.

selectorsarray of stringrequired

DKIM selectors this source is known to publish under. Matched against the selector of a key already in DNS; they are per-source conventions, not values to publish on a customer's behalf.

base_domainsarray of stringrequired

Domains this source signs from. A DKIM CNAME whose target sits under one of these belongs to this source, which is the only signal that identifies a per-customer selector such as HubSpot's hs1-<portal>.

page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Get a sending source

GET/sources/{id}requires auth

Fetch a single sending source by id. Authentication is optional, and instructions_curation is redacted as on the list endpoint.

Path parameters

idstring (uuid)required

Example request

curl "https://api.palisade.email/sources/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
idstring (uuid)required
external_idstringrequired
namestringrequired
homepagestring (uri), nullablerequired
base_domainsarray of stringrequired
categorystring enumrequired
One of: SENDING_TOOL, MAILBOX_PROVIDER, VPS_PROVIDER, SECURITY_PROVIDER, EMAIL_RELAY
dmarc_supportbooleanrequired
spf_supportstring enumrequired
One of: NONE, RARE, FULL
spf_support_optionsobjectrequired
properties
directobject, nullablerequired
properties
valuesarray of stringrequired
requires_advanced_configboolean, nullablerequired
subdomainobject, nullablerequired
properties
is_managedbooleanrequired
requires_user_selectionbooleanrequired
pathstring, nullablerequired
valuestring, nullablerequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
valuestring
dkim_supportstring enumrequired
One of: NONE, RARE, FULL
parent_source_idstring (uuid), nullable
display_namestring, nullable
envelope_fromsarray of stringrequired
is_custombooleanrequired
documentationobjectrequired
properties
spfstring, nullable
dkimstring, nullable
combinedstring, nullable
spf_reply_to_targetstring, nullablerequired
spf_supported_methodsarray of string enumrequired
items
One of: DIRECT, SUBDOMAIN, MANAGED_SUBDOMAIN
forwarding_typestring enumrequired
One of: NOT_FORWARDER, FORWARDER, FORWARDER_ONLY
dkim_discovery_selectorsarray of stringrequired
spf_discovery_valuesarray of stringrequired
spf_reply_to_discovery_valuesarray of stringrequired
mx_domainsarray of stringrequired
dkim_instructionsobject, nullablerequired
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME
namestring
valuestring
spf_instructionsobject, nullable
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
namestring
valuestring
instructions_curationobject, nullable
properties
dkimobject, nullable
properties
statusstring enumrequired
One of: PENDING, APPROVED, REJECTED
proposalobjectrequired
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
namestring
valuestring
provenanceobjectrequired
properties
doc_urlstringrequired
doc_titlestring, nullablerequired
doc_discoveredbooleanrequired
modelstringrequired
confidencenumberrequired
critic_notesarray of stringrequired
generated_atstringrequired
reviewed_atstring, nullable
reviewed_bystring, nullable
spfobject, nullable
properties
statusstring enumrequired
One of: PENDING, APPROVED, REJECTED
proposalobjectrequired
properties
stepsarray of stringrequired
dns_recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, CNAME, MX
namestring
valuestring
provenanceobjectrequired
properties
doc_urlstringrequired
doc_titlestring, nullablerequired
doc_discoveredbooleanrequired
modelstringrequired
confidencenumberrequired
critic_notesarray of stringrequired
generated_atstringrequired
reviewed_atstring, nullable
reviewed_bystring, nullable
statusstring enumrequired
One of: ACTIVE, PENDING_REVIEW, REJECTED
originstring enumrequired
One of: DMARC_IO, AI_DISCOVERED, MANUAL
ai_confidencenumber, nullablerequired
created_atstring (date-time)required
updated_atstring (date-time)required

Spf

Get SPF diagnostics

GET/domains/{domainId}/spfrequires auth

Path parameters

domainIdstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/domains/<domainId>/spf" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200SpfDiagnostics

Success

Response body
domain_idstring (uuid)required

Id of the domain the diagnostics are for.

domainstringrequired

The domain name whose live DNS was read, for example "example.com".

recordstring, nullablerequired

The SPF TXT record live DNS serves for the domain, or null when none is published. When more than one v=spf1 record exists they are joined with newlines here; see records for them individually.

recordsarray of stringrequired

Every v=spf1 TXT record found at the domain. More than one entry is itself an error — receivers treat it as a permanent failure.

ttlnumber, nullablerequired

TTL of the SPF TXT record in seconds, when it could be read.

statusstringrequired

Overall SPF health: "pass", "warn" or "fail".

lookup_countintegerrequired

DNS lookups the record costs receivers: every include, a, mx, ptr, exists and redirect term, counted recursively through every include and redirect. Terms receivers never reach are not charged: anything to the right of a matching all, and a redirect= in a record that also carries an all, which RFC 7208 section 6.1 says must be ignored.

max_lookupsintegerrequired

The limit SPF imposes before receivers return a permanent error: 10.

lookups_remainingintegerrequired

How many more lookups the record could add before breaking. 0 when at or over the limit.

lookup_breakdownarray of SpfLookuprequired

Every lookup in the chain, nested entries following their parent.

SpfLookup
mechanismstringrequired

The SPF term that costs the lookup: "include", "a", "mx", "ptr", "exists" or "redirect". "expanded-domain" marks a macro expansion, which costs none.

hoststring, nullablerequired

The operand the term queries, as published. Usually a hostname. A macro-bearing exists: carries the template here, and the substituted name follows as an expanded-domain entry when every macro in it could be resolved. A macro-bearing a:, mx: or ptr: carries the template here too, but is never expanded, so no expanded-domain entry follows it; only include: and redirect= operands are put through the macro resolver, and one whose macros all resolved reports the substituted name it queried here rather than the published template, under the note "macro-expanded" when that name publishes exactly one SPF record, and with error when it does not.

depthintegerrequired

Nesting depth: 0 for mechanisms in the domain's own record, 1 for those inside an include it references, and so on.

lookupsintegerrequired

DNS lookups this entry accounts for: itself plus everything nested under it. The expensive includes are the ones with the highest number here.

errorbooleanrequired

True when this lookup failed to resolve to a usable record.

notestring, nullablerequired

Extra context, such as "loop", "unresolved", or one of "macro-expanded" / "macro-unexpanded". Any term whose operand carries a macro -- exists:, include: or redirect= -- carries one of those two, and costs one lookup either way, except that an expanded include: or redirect= carries no macro note once its target disappoints: "unresolved" when the lookup could not be completed, "loop" when it refers back, "no-txt" alongside error when the target returned no TXT records at all, and no note at all -- just error -- when the target returned TXT records but not a single SPF record among them.

problemsarray of SpfProblemrequired

Problems found, errors before warnings. Empty when SPF is healthy.

SpfProblem
codestringrequired

Stable identifier for the problem, safe to branch on — for example "spf-max-10-lookups", "spf-multiple-records", "spf-lookup-failed" or "spf-no-record".

severitystring enumrequired

"error" when receivers fail SPF (or get no protection from it) because of this; "warning" for a risk that does not break evaluation.

One of: error, warning
hoststring, nullablerequired

The hostname the problem is about, when it concerns a specific lookup.

messagestringrequired

What is wrong and what it means for mail, in plain language.

hosted_spfobjectrequired

State of Palisade-hosted SPF for the domain. When managed, the domain publishes a single Palisade include and Palisade keeps the flattened chain under the 10-lookup limit.

properties
is_managedbooleanrequired

True when Palisade hosts and flattens the SPF record for this domain.

statusDnsStatus & object, nullablerequired

Live status of the hosted SPF chain, when managed.

target_spfstring, nullablerequired

The record Palisade flattens and publishes, when hosted SPF is configured.

error_reasonManagedDnsErrorReason & objectrequired

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.

last_flattened_atstring, nullablerequired

When Palisade last flattened and published the hosted chain, ISO 8601.

next_stepstringrequired

The single action Palisade suggests taking next.

Tool

Audit a domain

GET/tools/auditrequires auth

Run the full email-authentication audit against a domain from live DNS: MX, SPF, DKIM, DMARC, BIMI, MTA-STS and TLS-RPT, each scored and annotated, plus an overall score out of 100. The domain does not have to be one you have added to Palisade. Results are cached for ten minutes per domain. Authentication is optional. Note that this response predates the API-wide snake_case convention and keeps its original camelCase field names (mtaSts, lookupCount, dmarcValue), so it does not read like the rest of the API.

Query parameters

domainstringrequired
emailstring (email)
skip_dkimstring enum
One of: true, false
skip_webhooksstring enum
One of: true, false
store_scanstring enum
One of: true, false
utm_sourcestring

Headers

Palisade-Journey-Idstring (uuid)

The website visitor journey this audit belongs to, the same id sent to POST /attribution/touches. Read only when the request captures a lead, and ignored rather than rejected when it is missing or malformed.

Example request

curl "https://api.palisade.email/tools/audit" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200AuditResult

Success

Response body
statusstring enumrequired

"success", or "error" when the audit could not run because the domain's nameservers did not resolve or belong to a domain-parking advertiser. On "error" only summary is present, with the reason in summary.errors.

One of: success, error
summaryobjectrequired

The headline: the overall score and one verdict per dimension.

properties
hostnamestringrequired

The domain audited, as requested.

emailstringrequired

The email query parameter, echoed back. Empty when none was sent, and empty on the error status whether or not one was.

parkedbooleanrequired

True when Palisade has the domain on record as parked. A parked domain should send no mail, so only SPF and DMARC count toward its score.

scorenumberrequired

0-100: 100 less what each counted dimension loses, as each dimension's score reports.

mxstring

The MX verdict, the same value as mx.status.

spfstring

The SPF verdict, the same value as spf.status.

dkimstring

The DKIM verdict, the same value as dkim.status.

dmarcstring

The DMARC verdict, the same value as dmarc.status.

bimistring

The BIMI verdict, the same value as bimi.status.

mtaStsstring

The MTA-STS verdict, the same value as mtaSts.status.

tlsRptstring

The TLS-RPT verdict, the same value as tlsRpt.status.

errorsarray of stringrequired

Why the audit could not run: "ns-error" when the nameservers did not resolve, "ns-for-advertising-domain" when they belong to a domain-parking advertiser. Empty on success.

warningsarray of string

Always empty. Findings are reported on each dimension.

assessmentsarray of string

Always empty. Findings are reported on each dimension.

nameserversarray of string

The NS records the audit resolved: the domain's own, or its parent's when it has none.

mxobject

The MX check.

properties
scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

mxPresentobjectrequired

The MX check as a state: "mx-present" or "mx-missing".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

mxHoststringrequired

The name the MX records were read from: the audited domain, or for a subdomain with no nameservers of its own, the parent whose nameservers answered.

mxValuearray of objectrequired

The MX records found, most preferred first.

items
exchangestringrequired

The mail server hostname.

prioritynumberrequired

MX preference. Lower values are tried first.

resolutionFailedboolean

True when the MX lookup itself failed, so an empty mxValue is not evidence of absence.

spfobject

The SPF check, including what the record costs in DNS lookups.

properties
scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

spfSoftFailobjectrequired

The SPF record as a state, such as "spf-soft-fail" (ends in ~all), "spf-closed" (ends in -all), "spf-missing", "spf-multiple-records" or "spf-invalid".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

spfValuestringrequired

The SPF record evaluated: the redirect target's when the domain uses redirect= and that target publishes exactly one record, otherwise the domain's own; every record joined by newlines, longest first, when more than one is published. Empty only when no record was found, a deprecated record type is published, or the domain publishes a single record carrying redirect= alongside an all mechanism - a record that loops, over-runs the lookup limit or has an unresolved include is still reported here.

lookupCountnumberrequired

DNS lookups counted from every term RFC 7208 section 4.6.4 charges one for -- include, a, mx, ptr, exists and redirect -- whether or not each one resolved, and whatever qualifier it carries. Over 10 is an SPF permerror. Each term counts once and names the host it queries, includes and redirects are followed recursively wherever they appear, and ip4, ip6 and all cost nothing. Two terms are deliberately not charged, because receivers never query them: anything standing to the right of a matching all, and a redirect= in a record that also carries an all, which RFC 7208 section 6.1 says must be ignored.

lookupStructurearray of objectrequired

The DNS lookups the record costs receivers, as a tree: an include or redirect lists what it expands into under nested.

items
typestringrequired

The term that costs the lookup: "include", "redirect", "a", "mx", "ptr" or "exists". "expanded-domain" is the name an exists: macro expands to, which costs no lookup.

valuestring

The operand the term queries, as published rather than resolved -- with one exception: an include: or redirect= whose macros all resolved reports the substituted name it queried, under the note "macro-expanded" when that name publishes exactly one SPF record, and with error when it does not. A bare a, mx or ptr names the domain whose record it stands in, since that is what it queries: the audited domain at the top level, and the included or redirect target inside the subtree belonging to it. Two cases are not a hostname: an exists: carrying a macro is the template, and a nested expanded-domain node carries the substituted name only when %{i}, %{ir}, %{v} and %{d} are the only macros it uses -- any other macro form leaves the term unexpanded, carrying the note "macro-unexpanded" and no nested node; and an a:, mx: or ptr: carrying a macro, such as a:%{d}, is the template unexpanded, since only include: and redirect= operands are put through the macro resolver. A qualifier does not change the operand: ~a:mail.example.com and -mx:relay.example.net name the host each points at, exactly as the unqualified forms do.

nestedarray of object, nullable

The lookups this one expands into, each an SpfLookupNode.

notestring

"loop" for an include or redirect that refers back to a record already being evaluated, "unresolved" when the lookup could not be completed, "macro-expanded" for a term whose operand carried a macro that was substituted, and "macro-unexpanded" for one carrying a macro that cannot be resolved without a live sender. exists:, include: and redirect= can all carry either, and cost one lookup whichever it is -- except that an expanded include: or redirect= carries no macro note once its target disappoints: "unresolved" when the lookup could not be completed, "loop" when it refers back, "no-txt" alongside error when the target returned no TXT records at all, and no note at all -- just error -- when the target returned TXT records but not a single SPF record among them. An expanded exists: puts the substituted name in a nested expanded-domain node; an expanded include: or redirect= queries the substituted name and reports it as the value.

errorboolean

True when the include or redirect target publishes no single SPF record, or loops. A lookup that could not be completed carries the note "unresolved" and no error instead, and a target that returned no TXT records at all carries error together with the note "no-txt".

resolutionFailedboolean

True when the SPF lookup itself failed, for the domain or its redirect= target, so what errors reports missing is not evidence of absence.

servicesarray of object, nullablerequired

Always empty.

deprecatedbooleanrequired

True when the domain still publishes the obsolete SPF record type (DNS type 99), which receivers ignore.

ip4Rangesarray of stringrequired

The ip4: ranges the record authorizes itself, not counting its includes. Empty when the record could not be evaluated.

ip6Rangesarray of stringrequired

The ip6: ranges the record authorizes itself, not counting its includes. Empty when the record could not be evaluated.

ttlnumber, nullablerequired

TTL of the SPF record in seconds, from the domain's authoritative nameservers. 0 or null when it could not be read.

recommendationsarray of stringrequired

Improvements worth making beyond errors and warnings, as codes such as "dmarc-policy-quarantine", which urges moving on to reject. Usually empty.

dkimobject

The DKIM check, over the selectors Palisade knows to probe.

properties
scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

hostnamestringrequired

The domain whose DKIM selectors were checked.

dkimValuesarray of objectrequired

Every DKIM record found. Palisade probes only the selectors its catalogue of sending services uses, so a key under any other selector is not found: an empty list is not proof the domain has no DKIM.

items
recordstringrequired

The TXT record published at the selector.

selectorstringrequired

The selector, published at <selector>._domainkey.<domain>.

sourcestringrequired

The sending service in Palisade's catalogue that uses this selector.

kstringrequired

The key type from k=, such as "rsa". Empty when the tag is absent, which means rsa.

pstringrequired

The public key from p=. Empty when the key is revoked (p= with no value) or the tag is missing.

scorenumberrequired

Points this record takes off the DKIM score. 0 when it is sound.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

dmarcobject

The DMARC check, which scores the policy and the reporting separately.

properties
hostnamestringrequired

The domain the DMARC record was read from: the audited domain, or the parent it was found on when the audited domain publishes none.

scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

setupStatestringrequired

Whether the record already sends aggregate reports to Palisade: "SETUP" if so, otherwise "NONE".

dmarcClosedobjectrequired

The policy half as a state: "dmarc-policy-none", "dmarc-policy-quarantine-*" or "dmarc-policy-reject-*" by pct= level (low, medium, high or full), "dmarc-missing" or "dmarc-invalid".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

dmarcMonitoredobjectrequired

The reporting half as a state: "dmarc-monitoring-managed" (aggregate reports reach Palisade), "dmarc-monitoring-external" (they go elsewhere), "dmarc-monitoring-missing" or "dmarc-monitoring-invalid".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

recordsarray of stringrequired

Every v=DMARC1 record found. More than one is an error: receivers then ignore DMARC.

dmarcValuestring, nullable

The record evaluated. Null when none was found or more than one is published.

ttlnumber, nullablerequired

TTL of the DMARC record in seconds, from the authoritative nameservers. Null when it could not be read.

tagsobjectrequired

The tags the record sets, parsed. A tag it omits is null, or an empty list.

properties
policystring, nullablerequired

The p= policy, lowercased: "none", "quarantine" or "reject".

pctnumber, nullablerequired

The pct= percentage of failing mail the policy applies to. Null when absent, which means 100.

fostring, nullablerequired

The fo= failure-reporting option: "0", "1", "d" or "s".

ruaMailtoarray of stringrequired

Where aggregate reports go: the rua= addresses, without mailto:.

rufMailtoarray of stringrequired

Where failure reports go: the ruf= addresses, without mailto:.

adkimstring, nullablerequired

The adkim= DKIM alignment mode: "r" relaxed or "s" strict. Null when absent, which means relaxed.

aspfstring, nullablerequired

The aspf= SPF alignment mode: "r" relaxed or "s" strict. Null when absent, which means relaxed.

spstring, nullablerequired

The sp= policy for subdomains. Null when absent, in which case subdomains take p=.

monitoringarray of stringrequired

Reporting findings, kept apart from errors: codes such as "dmarc-missing-rua-tag", which means no aggregate reports are requested.

recommendationsarray of stringrequired

Improvements worth making beyond errors and warnings, as codes such as "dmarc-policy-quarantine", which urges moving on to reject. Usually empty.

viaCnamebooleanrequired

True when the record is served through a CNAME rather than published directly.

isPalisadeCnamebooleanrequired

True when that CNAME points at Palisade, which hosts the record.

resolutionFailedbooleanrequired

True when the DMARC lookup itself failed, so what errors reports missing is not evidence of absence.

bimiobject

The BIMI check, including the logo and certificate the record links to.

properties
scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

bimiCertifiedobjectrequired

The BIMI record as a state: "bimi-certified" (a logo and a certificate), "bimi-uncertified" (a logo without one), "bimi-missing", "bimi-invalid", "bimi-requirements-not-met" (DMARC is not at enforcement), or once the files are checked "bimi-logo-invalid", "bimi-vmc-invalid" or "bimi-vmc-expired".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

bimiValuestring, nullablerequired

The record at default._bimi.<domain>. Null when none, or more than one, is published.

locationstring, nullablerequired

The logo URL from l=. Null when the tag is absent.

assertionstring, nullablerequired

The a= value as published, kept verbatim: an https:// .pem URL where the tag carries one, otherwise the literal "self", an empty string, or whatever unusable value was set. A usable URL here is not a verdict on the certificate, because it is not cleared when the record later fails its checks - read bimiCertified for that. Null when the tag is absent or was not reached.

recommendationsarray of stringrequired

Improvements worth making beyond errors and warnings, as codes such as "dmarc-policy-quarantine", which urges moving on to reject. Usually empty.

vmcExpiryDatestring (date-time)

When the certificate expires, taken from its validTo. Present when validation read a validTo, or when a cached expiry from an earlier read was reused; absent when the certificate could not be fetched or parsed, even though it was reached.

viaCnamebooleanrequired

True when the record is served through a CNAME rather than published directly.

isPalisadeCnamebooleanrequired

True when that CNAME points at Palisade, which hosts the record.

deepValidatedboolean

True when this audit attempted deep validation: fetching the logo, and the certificate when a= names one. It is set before those fetches run, so it does not mean either succeeded - read logoValidation and vmcValidation for that. Absent when the record failed before that step, and when a VMC result checked within the last 24 hours was reused instead of re-reading it.

logoValidationobject

What fetching and checking the logo at location found. Present when deepValidated is true.

properties
fetchedbooleanrequired

True when the logo could be downloaded.

validbooleanrequired

True when it passed Palisade's checks for a BIMI SVG.

errorstring, nullablerequired

Why the logo failed, when it did.

vmcValidationobject

What fetching and checking the certificate at assertion found. Present when deepValidated is true and a= names a certificate.

properties
fetchedbooleanrequired

True when the certificate file could be downloaded.

validbooleanrequired

True when every certificate check passed. Warnings such as a logo mismatch do not count against it.

certificateCountnumberrequired

PEM certificates in the file.

chainCompleteboolean, nullablerequired

True when the file carries every certificate from the leaf up to a self-signed root. Null until checked.

chainTrustedboolean, nullablerequired

True when the chain, exactly as published, ends in a root Palisade trusts for BIMI. Null until checked.

trustAnchorstring, nullablerequired

The trusted root the chain ends in. Null when it is not trusted.

markTypePresentboolean, nullablerequired

True when the certificate carries the BIMI mark-type attribute a VMC or CMC must have. Null until checked.

isVmcboolean, nullablerequired

True when it is a mark certificate, one that embeds a logo; false when it is another kind of certificate; null when it could not be read.

logoMatchesCertificateboolean, nullablerequired

True when the logo at location is byte for byte the one embedded in the certificate. Null when they were not compared.

domainCoveredboolean, nullablerequired

True when the certificate names the audited domain. Null until checked.

issuerstring, nullablerequired

Common name of the certificate's issuer.

subjectCommonNamestring, nullablerequired

Common name the certificate was issued to.

validFromstring, nullablerequired

Start of the validity period, ISO 8601.

validTostring, nullablerequired

End of the validity period, ISO 8601.

sanDomainsarray of stringrequired

The domains the certificate covers, from its subject alternative names.

errorstring, nullablerequired

Why the certificate failed, when it did.

mtaStsobject

The MTA-STS check. It does not count toward the overall score.

properties
scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

mtaStsStatusobjectrequired

The MTA-STS setup as a state: "mta-sts-enforce", "mta-sts-testing", "mta-sts-none-mode", "mta-sts-missing", "mta-sts-dns-only" (a TXT record but no reachable policy), "mta-sts-mx-mismatch" (the policy misses an MX host) or "mta-sts-invalid".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

txtValuestring, nullablerequired

The record at _mta-sts.<domain>. Null when none, or more than one, is published.

policyFilestring, nullablerequired

The policy served at https://mta-sts.<domain>/.well-known/mta-sts.txt, verbatim. Null when it could not be fetched.

modestring, nullablerequired

The policy mode: "enforce", "testing" or "none". Null when there is no policy to read.

mxEntriesarray of stringrequired

The mx: patterns the policy covers.

maxAgenumber, nullablerequired

The policy max_age in seconds. Null when there is no readable value.

policyIdstring, nullablerequired

The id= of the TXT record. Senders fetch the policy again when it changes.

tlsRptobject

The TLS-RPT check. It does not count toward the overall score.

properties
scorenumberrequired

Points this dimension takes off the overall score: 0 at full marks, negative otherwise. Only MX, SPF, DKIM, DMARC and BIMI are counted, and only SPF and DMARC when the domain is parked.

statusstringrequired

Verdict: "pass", "warn" or "fail"; "in progress" for a DMARC policy short of full reject or MTA-STS in testing mode; "info" when optional MTA-STS or TLS-RPT is not set up. DKIM reports "error" when the catalogue of sending services Palisade probes was unavailable, so no selector was probed and the result says nothing about the domain.

assessmentsarray of stringrequired

What was found that is not a problem, such as "spf-success". MTA-STS and TLS-RPT write sentences instead of codes.

errorsarray of stringrequired

Problems that break or undermine the mechanism, as stable codes such as "spf-no-record". A host can follow a colon, as in "spf-lookup-failed:spf.example.com". MTA-STS and TLS-RPT write sentences instead of codes.

warningsarray of stringrequired

Risks worth fixing that do not break the mechanism, such as "spf-low-ttl". MTA-STS and TLS-RPT write sentences instead of codes.

tlsRptStatusobjectrequired

The TLS-RPT record as a state: "tls-rpt-present", "tls-rpt-missing" or "tls-rpt-invalid".

properties
statusstringrequired

The verdict this state carries: "pass", "warn", "fail", "in progress" or "info".

statestringrequired

Stable identifier for what was found, safe to branch on. The field holding this object lists its values.

scorenumberrequired

Points this state earns toward its dimension. Unlike the dimension's own score, it counts up from 0.

penaltiesarray of stringrequired

Codes for lesser problems found alongside the state, such as "spf-ptr-unrecommended". Usually empty.

txtValuestring, nullablerequired

The record at _smtp._tls.<domain>. Null when none, or more than one, is published.

reportingEndpointsarray of stringrequired

Where TLS failure reports go: the valid rua= destinations, each mailto: or https://.

Read a stored activation scan

GET/tools/activation-scan

Return the most recent audit stored for a domain by GET /tools/audit?store_scan=true, so a scan run on the marketing site survives the sign-up round trip without being run again. Reports the same public DNS findings the audit does, and expires 24 hours after the scan. Authentication is not required.

Query parameters

domainstringrequired

Example request

curl "https://api.palisade.email/tools/activation-scan"

Responses

200object

Success

Response body
schemaVersionnumber enumrequired
One of: 1
domainstringrequired
Max length: 253
scorenumberrequired
Min: 0 · Max: 100
issueCountintegerrequired
Min: 0 · Max: 7
findingsarray of objectrequired
items
idstringrequired
keystring enumrequired
One of: mx, spf, dkim, dmarc, bimi, mtaSts, tlsRpt
titlestringrequired
Min length: 1 · Max length: 32
severitystring enumrequired
One of: fail, warn, info
detailstringrequired
Min length: 1 · Max length: 1000
optionalbooleanrequired
diagnosticsarray of object
items
codestringrequired
Min length: 1 · Max length: 2000
detailstringrequired
Min length: 1 · Max length: 1000
selectorstring
Max length: 253
baselineobjectrequired
properties
dmarcValuestring, nullablerequired
Max length: 8192
initialTasksarray of objectrequired
items
typestring enumrequired
One of: SET_UP_MX_RECORD, SET_UP_SPF_RECORD, CLEANUP_SPF_RECORD, REDUCE_SPF_LOOKUPS
priorityintegerrequired
Min: 1 · Max: 3
descriptionstringrequired
Min length: 1 · Max length: 500
providerobject, nullablerequired
properties
namestringrequired
Min length: 1 · Max length: 128
domainstringrequired
Max length: 253
sourceToolstring enumrequired
One of: email-security-score
scannedAtstring (date-time)required
expiresAtstring (date-time)required

Identify the mailbox provider

GET/tools/mailbox-providerrequires auth

Identify which mailbox provider hosts a domain's inbound mail, from its live MX records. Returns a null provider when the MX records match no known provider, when the domain has no MX at all, or when a security gateway sits in front and hides the provider behind it. Authentication is optional.

Query parameters

domainstringrequired

Example request

curl "https://api.palisade.email/tools/mailbox-provider" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200MailboxProviderResult

Success

Response body
domainstringrequired
providerobject, nullablerequired

Null when the MX records match no known mailbox provider, or when the domain has no MX at all.

properties
idstringrequired
namestringrequired
urlstringrequired

Validate an SPF include

GET/tools/validate-includerequires auth

Check that a domain is usable as an SPF include: and count the DNS lookups it costs, so you can tell before adding it whether it will push a record past the ten-lookup limit. The count includes the include itself. Callable with an API key or a dashboard session. The browser tool reaches this same endpoint with a captcha token instead, which is why you may see it called without credentials; a captcha is not something an API client can produce, so it is not part of this contract.

Query parameters

domainstringrequired

The domain to test as an SPF include: target, e.g. _spf.google.com.

Example request

curl "https://api.palisade.email/tools/validate-include" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200ValidateIncludeResult

Success

Response body
validbooleanrequired
lookup_countnumber

DNS lookups the include costs, counting the include itself. Only present when valid is true.

errorstring

Why the domain is not usable as an SPF include. Only present when valid is false.

Look up DNS records

POST/tools/dns-lookuprequires auth

Read a host's TXT, MX, NS, A and CNAME records from live DNS in one call. Record types that resolve to nothing are simply absent from the array rather than reported as an error. Authentication is optional.

Request body

hoststringrequired

The host to resolve.

Example request

curl -X POST "https://api.palisade.email/tools/dns-lookup" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "host": "string"
}'

Responses

200DnsLookupResult

Success

Response body
recordsarray of objectrequired
items
typestring enumrequired
One of: TXT, MX, NS, A, CNAME
valuestringrequired
prioritynumber

MX preference. Only present on MX records.

Analyze email headers

POST/tools/header-analyzerequires auth

Parse a raw email header block and report what the receiving path concluded: the SPF, DKIM and DMARC verdicts each hop recorded, whether those domains align with the From domain, the DKIM signatures and ARC chain present, and the delivery hops with the delay at each. With include_dns_validation left on, the From domain's SPF, DMARC and DKIM records are also read from live DNS so a verdict can be checked against what is published now. Callable with an API key or a dashboard session. The browser tool reaches this same endpoint with a captcha token instead, which is why you may see it called without credentials; a captcha is not something an API client can produce, so it is not part of this contract. The request body is snake_case, but the analysis in the response keeps camelCase field names (authenticationResults, receivedHops, dnsValidation) rather than the API-wide convention.

Request body

headersstringrequired
Min length: 10 · Max length: 100000
include_dns_validationboolean
Default: true

Example request

curl -X POST "https://api.palisade.email/tools/header-analyze" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "headers": "string",
  "include_dns_validation": true
}'

Responses

200HeaderAnalysisResult

Success

Response body
summaryobjectrequired
properties
fromstringrequired
returnPathstringrequired
subjectstringrequired
datestringrequired
messageIdstringrequired
spfstringrequired

pass, fail, softfail, neutral, none, temperror, permerror or unknown.

dkimstringrequired

pass, fail, softfail, neutral, none, temperror, permerror or unknown.

dmarcstringrequired

pass, fail, softfail, neutral, none, temperror, permerror or unknown.

spfAlignmentstringrequired

Whether the SPF domain aligns with the From domain, strictly or relaxed.

dkimAlignmentstringrequired
overallVerdictstringrequired
authenticationResultsarray of objectrequired
items
authServIdstringrequired
spfstringrequired

pass, fail, softfail, neutral, none, temperror, permerror or unknown.

spfReasonstringrequired
spfFromstringrequired
dkimstringrequired

pass, fail, softfail, neutral, none, temperror, permerror or unknown.

dkimReasonstringrequired
dkimDomainstringrequired
dmarcstringrequired

pass, fail, softfail, neutral, none, temperror, permerror or unknown.

dmarcReasonstringrequired
compAuthstringrequired

Microsoft's composite authentication verdict, when present.

rawstringrequired
dkimSignaturesarray of objectrequired
items
versionstringrequired
algorithmstringrequired
domainstringrequired
selectorstringrequired
headerFieldsstringrequired
bodyHashstringrequired
rawstringrequired
arcChainarray of objectrequired
items
instancenumberrequired
arcAuthenticationResultsstringrequired
arcSealstringrequired
arcMessageSignaturestringrequired
cvstringrequired
receivedHopsarray of objectrequired
items
indexnumberrequired
fromstringrequired
bystringrequired
protocolstringrequired
timestampstringrequired
delayMsnumber, nullablerequired

Milliseconds spent at this hop, or null when it cannot be derived.

ipstringrequired
rawstringrequired
dnsValidationobject, nullablerequired

Live DNS read for the From domain. Null when include_dns_validation was false.

properties
fromDomainstringrequired
spfRecordstring, nullablerequired
dmarcRecordstring, nullablerequired
dmarcPolicystring, nullablerequired
dkimSelectorsarray of objectrequired
items
selectorstringrequired
domainstringrequired
publicKeyFoundbooleanrequired
warningsarray of stringrequired
rawHeaderCountnumberrequired

Webhooks

List webhook endpoints

GET/webhook-endpointsrequires auth

Query parameters

pagenumber
per_pagenumber

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/webhook-endpoints" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of WebhookEndpointrequired
WebhookEndpoint
idstring (uuid)required
urlstring (uri)required
descriptionstring, nullablerequired
enabled_eventsarray of string enumrequired

Event types this endpoint receives. An empty array means every event, including ones added later — not none.

items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enumrequired

ENABLED receives events. DISABLED was turned off by you. AUTO_DISABLED was turned off by Palisade after repeated delivery failures and stays off until you re-enable it, which also clears the failure count.

One of: ENABLED, DISABLED, AUTO_DISABLED
secret_reminderstringrequired

Last 4 characters of the signing secret. The full secret is returned only at creation.

api_versionstringrequired

API version the payload shape is pinned to, captured when the endpoint was created.

consecutive_failuresnumberrequired
Min: 0
disabled_reasonstring, nullablerequired
last_success_atstring (date-time), nullablerequired
last_failure_atstring (date-time), nullablerequired
created_bystringrequired
created_atstring (date-time)required
updated_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

Create a webhook endpoint

POST/webhook-endpointsrequires auth

Creates an endpoint. The response is the only time the signing secret is returned in full; store it immediately.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

urlstring (uri)required
descriptionstring
Max length: 500
enabled_eventsarray of string enum

Event types this endpoint receives. Omit it, or send an empty array, to receive every event including ones added later.

items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted

Example request

curl -X POST "https://api.palisade.email/webhook-endpoints" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com",
  "description": "string",
  "enabled_events": [
    "domain.created"
  ]
}'

Responses

201WebhookEndpointWithSecret

Created

Response body
idstring (uuid)required
urlstring (uri)required
descriptionstring, nullablerequired
enabled_eventsarray of string enumrequired

Event types this endpoint receives. An empty array means every event, including ones added later — not none.

items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enumrequired

ENABLED receives events. DISABLED was turned off by you. AUTO_DISABLED was turned off by Palisade after repeated delivery failures and stays off until you re-enable it, which also clears the failure count.

One of: ENABLED, DISABLED, AUTO_DISABLED
secret_reminderstringrequired

Last 4 characters of the signing secret. The full secret is returned only at creation.

api_versionstringrequired

API version the payload shape is pinned to, captured when the endpoint was created.

consecutive_failuresnumberrequired
Min: 0
disabled_reasonstring, nullablerequired
last_success_atstring (date-time), nullablerequired
last_failure_atstring (date-time), nullablerequired
created_bystringrequired
created_atstring (date-time)required
updated_atstring (date-time)required
secretstringrequired

The signing secret, shown once. Store it now; it cannot be retrieved later.

Get a webhook endpoint

GET/webhook-endpoints/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/webhook-endpoints/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200WebhookEndpoint

Success

Response body
idstring (uuid)required
urlstring (uri)required
descriptionstring, nullablerequired
enabled_eventsarray of string enumrequired

Event types this endpoint receives. An empty array means every event, including ones added later — not none.

items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enumrequired

ENABLED receives events. DISABLED was turned off by you. AUTO_DISABLED was turned off by Palisade after repeated delivery failures and stays off until you re-enable it, which also clears the failure count.

One of: ENABLED, DISABLED, AUTO_DISABLED
secret_reminderstringrequired

Last 4 characters of the signing secret. The full secret is returned only at creation.

api_versionstringrequired

API version the payload shape is pinned to, captured when the endpoint was created.

consecutive_failuresnumberrequired
Min: 0
disabled_reasonstring, nullablerequired
last_success_atstring (date-time), nullablerequired
last_failure_atstring (date-time), nullablerequired
created_bystringrequired
created_atstring (date-time)required
updated_atstring (date-time)required

Update a webhook endpoint

POST/webhook-endpoints/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Request body

urlstring (uri)
descriptionstring, nullable
Max length: 500
enabled_eventsarray of string enum
items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enum
One of: ENABLED, DISABLED

Example request

curl -X POST "https://api.palisade.email/webhook-endpoints/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com",
  "description": "string",
  "enabled_events": [
    "domain.created"
  ],
  "status": "ENABLED"
}'

Responses

200WebhookEndpoint

Success

Response body
idstring (uuid)required
urlstring (uri)required
descriptionstring, nullablerequired
enabled_eventsarray of string enumrequired

Event types this endpoint receives. An empty array means every event, including ones added later — not none.

items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enumrequired

ENABLED receives events. DISABLED was turned off by you. AUTO_DISABLED was turned off by Palisade after repeated delivery failures and stays off until you re-enable it, which also clears the failure count.

One of: ENABLED, DISABLED, AUTO_DISABLED
secret_reminderstringrequired

Last 4 characters of the signing secret. The full secret is returned only at creation.

api_versionstringrequired

API version the payload shape is pinned to, captured when the endpoint was created.

consecutive_failuresnumberrequired
Min: 0
disabled_reasonstring, nullablerequired
last_success_atstring (date-time), nullablerequired
last_failure_atstring (date-time), nullablerequired
created_bystringrequired
created_atstring (date-time)required
updated_atstring (date-time)required

Delete a webhook endpoint

DELETE/webhook-endpoints/{id}requires auth

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X DELETE "https://api.palisade.email/webhook-endpoints/<id>" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Deleted

Response body
deletedbooleanrequired
objectstringrequired
idstring (uuid)required

Rotate the signing secret

POST/webhook-endpoints/{id}/rotate-secretrequires auth

Issues a new signing secret and returns it once. The previous secret stops being valid immediately, so deliveries signed with it will fail verification.

Path parameters

idstring (uuid)required

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl -X POST "https://api.palisade.email/webhook-endpoints/<id>/rotate-secret" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200WebhookEndpointWithSecret

Success

Response body
idstring (uuid)required
urlstring (uri)required
descriptionstring, nullablerequired
enabled_eventsarray of string enumrequired

Event types this endpoint receives. An empty array means every event, including ones added later — not none.

items
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enumrequired

ENABLED receives events. DISABLED was turned off by you. AUTO_DISABLED was turned off by Palisade after repeated delivery failures and stays off until you re-enable it, which also clears the failure count.

One of: ENABLED, DISABLED, AUTO_DISABLED
secret_reminderstringrequired

Last 4 characters of the signing secret. The full secret is returned only at creation.

api_versionstringrequired

API version the payload shape is pinned to, captured when the endpoint was created.

consecutive_failuresnumberrequired
Min: 0
disabled_reasonstring, nullablerequired
last_success_atstring (date-time), nullablerequired
last_failure_atstring (date-time), nullablerequired
created_bystringrequired
created_atstring (date-time)required
updated_atstring (date-time)required
secretstringrequired

The signing secret, shown once. Store it now; it cannot be retrieved later.

List webhook deliveries

GET/webhook-endpoints/{id}/deliveriesrequires auth

Path parameters

idstring (uuid)required

Query parameters

pagenumber
per_pagenumber
statusstring enum
One of: PENDING, SUCCEEDED, FAILED

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/webhook-endpoints/<id>/deliveries" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of WebhookDeliveryrequired
WebhookDelivery
idstring (uuid)required
event_idstringrequired
event_typestring enumrequired
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
statusstring enumrequired
One of: PENDING, SUCCEEDED, FAILED
attemptsnumberrequired
Min: 0
response_statusnumber, nullablerequired
error_messagestring, nullablerequired
delivered_atstring (date-time), nullablerequired
created_atstring (date-time)required
page_infoobjectrequired
properties
countnumberrequired
pagenumberrequired
per_pagenumberrequired

List webhook event types

GET/webhook-eventsrequires auth

The catalogue of event types an endpoint can subscribe to.

Headers

Palisade-VersionApiVersionrequired
One of: 2025-04-30, unstable

Example request

curl "https://api.palisade.email/webhook-events" \
  -u "$PALISADE_API_KEY:" \
  -H "Palisade-Version: 2025-04-30"

Responses

200object

Success

Response body
dataarray of WebhookEventDescriptorrequired
WebhookEventDescriptor
typestring enumrequired
One of: domain.created, domain.updated, domain.deleted, domain.monitoring.activated, domain.monitoring.failed, domain.monitoring.drifted, domain.monitoring.recovered, domain.hosted_record.ready, domain.hosted_record.error, domain.score_changed, domain.policy_changed, mta_sts.enabled, mta_sts.updated, mta_sts.disabled, task.opened, task.completed, task.canceled, task.dismissed, task.reopened, organization.updated, member.added, member.updated, member.removed, invitation.created, invitation.revoked, group.created, group.updated, group.deleted
descriptionstringrequired
payload_typestringrequired