---
title: "Get the remediation plan"
method: GET
path: "/domains/{domainId}/plan"
tags: ["Domain"]
---

# Get the remediation plan

`GET /domains/{domainId}/plan`

## Request

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

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

- `domainId` string, uuid, required

## Headers

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

## Response `200`

Success

- DomainPlan
  - `scan_findings` object, nullable: Saved onboarding findings, including those without an actionable ticket. Not a fresh DNS audit.
    - `scanned_at` string, date-time, required
    - `items` object[], required
      - `id` string, required
      - `title` string, required
      - `detail` string, required
      - `code` string, required
      - `status` 'open' | 'verifying' | 'snoozed' | 'ticket_completed' | 'upcoming' | 'waiting' | 'optional' | 'review', required
      - `guidance` string, required
      - `tasks` object[], required
        - `id` string, uuid, required
        - `status` string, required
      - `task_types` string[], required: 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.
  - `domain_id` string, uuid, required
  - `domain` string, required: The domain this plan is for.
  - `is_parked` boolean, required: True when the domain is parked. A parked domain is monitored but has no journey to work through.
  - `agent_proposals_enabled` boolean, required: 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_stage` integer, nullable, required: The number of the stage being worked now, or null when none is current.
  - `stages` PlanStage[], required: The four stages of the DMARC journey, in order.
    - `number` integer, required: Position in the journey, 1 through 4.
    - `key` string, required: Stable identifier: "setup", "alignment", "enforcement" or "monitoring".
    - `title` string, required
    - `description` string, required
    - `status` 'completed' | 'current' | 'pending', required: "completed" when the stage is done, "current" for the one being worked, "pending" for one not started.
    - `steps` PlanStep[], required: The work this stage is made of. Empty for a parked domain.
      - `key` string, required: 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_type` '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', nullable, required: 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.
      - `title` string, required: What the step asks for, in plain language.
      - `description` string, required: Why the step matters.
      - `priority` integer, required: 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_gain` integer, required: How many points of the domain's audit score completing this step would win back. 0 when none.
      - `status` 'in_progress' | 'upcoming', required: "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.
      - `task_ids` string[], 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_steps` PlanOptionalStep[], required: Improvements worth making at this stage that Palisade does not require.
      - `key` string, required: Stable identifier for the optional step, for example "enable-hosted-spf".
      - `title` string, required
      - `description` string, required
      - `recommended` boolean, required: True when Palisade actively suggests it for this domain right now.
  - `upcoming_steps` PlanStep[], required: 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.
    - `key` string, required: 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_type` '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', nullable, required: 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.
    - `title` string, required: What the step asks for, in plain language.
    - `description` string, required: Why the step matters.
    - `priority` integer, required: 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_gain` integer, required: How many points of the domain's audit score completing this step would win back. 0 when none.
    - `status` 'in_progress' | 'upcoming', required: "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.
    - `task_ids` string[], 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.

---

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