---
title: "Validate a post (dry run)"
method: POST
path: "/v1/posts/validate"
tags: ["Posts"]
---

# Validate a post (dry run)

`POST /v1/posts/validate`

## Request

- Base URL: `https://api.postlake.dev`
- URL: `https://api.postlake.dev/v1/posts/validate`
- Auth: `bearerAuth` (a scheme the document does not define)

Runs the exact validation a publish would run, covering account resolution, media resolution and capability-registry rules, without touching any platform. Returns per-target errors (blocking) and warnings (advisory). Free to call before POST /v1/posts.

## Request body

- object
  - `text` string, required: Caption for feed posts and Reels. May be empty for an Instagram Story-only post; Instagram Stories do not display captions.
  - `campaign` string: Optional lowercase campaign slug, up to 80 characters.
  - `assetMetadata` object: Up to 16 short caller-defined fields, such as hook, track or source filename.
  - `profile` string: A profile name. Resolves to every account it owns. The simple way to address accounts; combine with `platforms` to narrow it. Provide `profile`, `accounts`, or both.
  - `platforms` Platform[]: Optional filter. Keeps only these networks from the resolved set.
  - `accounts` string[]: Connected account ids (acc_…). An alternative (or addition) to `profile`.
  - `media` string[]
  - `scheduledAt` string, date-time
  - `timezone` string: IANA timezone (e.g. Europe/London). Interprets a naive scheduledAt as wall time in that zone. Stored fire time is always UTC.
  - `platformOptions` object

## Response `200`

Validation result

- object
  - `ok` boolean, required
  - `targets` object[], required
    - `account` string, required
    - `platform` 'bluesky' | 'threads' | 'x' | 'linkedin' | 'instagram' | 'tiktok' | 'facebook' | 'youtube' | 'pinterest', required
    - `ok` boolean, required
    - `errors` string[], required: Blocking problems, as sentences. See `issues` for the actionable form.
    - `warnings` string[], required: Advisory: the post publishes, but something changes (e.g. images dropped).
    - `issues` object[], required: The same code / fix / param a real publish would return, so a dry run teaches exactly what the live call teaches.
      - `code` string, required
      - `message` string, required
      - `fix` string, required
      - `param` string
      - `docs` string, uri, required

## Other responses

- `400`: Invalid input
- `401`: Unauthorized

---

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