---
title: "Check the draft for problems before publishing"
method: POST
path: "/api/v1/sites/{slug}/preflight"
tags: ["Draft & publish"]
---

# Check the draft for problems before publishing

`POST /api/v1/sites/{slug}/preflight`

## Request

- Base URL: `https://api.dotsy.ai`
- URL: `https://api.dotsy.ai/api/v1/sites/{slug}/preflight`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

A read-only plan check over the draft: route and page counts, collection and template mistakes, redirect loops and chains, pages whose bytes are missing, pending third-party integrations and SEO notes. Run it before a large build and again before `publishSite`. It reads the whole site, so call it on demand rather than in a loop. It records a draft SEO snapshot, which the dashboard shows.

## Path parameters

- `slug` string, required

## Request body

- SitePreflightRequest: What you plan to add. Both fields are optional and the body can be empty.
  - `requiredRoutes` integer: How many routes you plan to add. It is counted against the Free plan's soft limit of about 10 routes.
  - `requiredAssets` integer: How many assets you plan to upload. Used to remind you to upload them before publishing.

## Response `200`

The findings. Read `ok` and `suggestions`.

- SitePreflightResult
  - `ok` boolean, required: False when any blocking suggestion exists. Suggestions ending in `(advisory)`, `(optional)` or `(info)` never flip it.
  - `slug` string, required
  - `collections` object, required: The site's collection index by prefix (item count, build state, data size).
  - `integrations` object, required: Third-party scripts found on imported pages that still need a decision. They never block a publish.
    - `pending` object[], required
      - `id` string, required
      - `vendor` string, required
      - `sourceId` string, required
      - `status` string, required
      - `pageCount` integer, required
      - `mayAffectUi` boolean
  - `stats` object, required
    - `pages` integer, required
    - `assets` integer, required
    - `htmlPages` integer, required
  - `routes` object, required
    - `count` integer, required
    - `softLimit` integer, required: The Free plan's advisory route limit.
    - `required` integer, required: The `requiredRoutes` you sent.
    - `partial` true: The route or page scan hit its cap, so some redirect checks may be incomplete.
  - `suggestions` string[], required: Plain-language findings: collection and template problems, redirect loops, SEO notes, missing page bytes.
  - `blocking` string[], required: The `suggestions` that made `ok` false, word for word. Empty when `ok` is true. Fix these first.
  - `contentBytesIssues` object[]: Pages whose stored bytes are missing or empty: re-write them before publishing.
    - `key` string, required
    - `reason` 'missing' | 'empty', required
  - `sharedSectionSuggestions` SharedSectionNudge: Blocks that repeat across pages and could become shared sections. Never blocks; absent when there are none.
    - `count` integer, required: Blocks with an exact copy on 3 or more pages that are not shared or dismissed.
    - `next` 'share_section', required: The next step: MCP `share_section` with no arguments (or GET …/shared-sections/suggestions) lists them.

## Other responses

- `401`: Missing or invalid credentials.
- `403`: This is a POST, so a viewer role (`forbidden_role`) or a read-only key (`forbidden_read_only`) is refused, as is a key scoped to other sites (`forbidden_site_scope`).
- `404`: No such site, or it is not visible to this account (`not_found`).

---

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