---
title: "Update a post by ID"
method: PUT
path: "/v1/posts/{postId}"
tags: ["posts"]
---

# Update a post by ID

`PUT /v1/posts/{postId}`

Update an existing post in your publication. The publication is identified by the API key provided in the Authorization header.

**Behavior:**
- Only provided fields are updated; omitted fields remain unchanged
- When `markdown` is provided, it replaces the full content. Rich blocks (embeds, buttons, callouts) created in the editor will be lost — the markdown to editor conversion is lossy for blocks without a markdown equivalent
- Set `status` to `"published"` to publish a draft, `"draft"` to unpublish, or `"archived"` to archive
- Set `scheduledAt` (Unix timestamp in milliseconds) to schedule a draft's first-publish for a future time. Must be in the future and at most 30 days out. Only valid for posts that haven't been published or already scheduled. Pass `scheduledAt: null` to cancel a previously scheduled publish (or to reschedule: cancel first, then schedule again with the new time). Set `sendNewsletter: true` alongside `scheduledAt` to email subscribers when the post publishes.

## Path parameters

- `postId` string, required

## Request body

- object
  - `markdown` string — Post content in Markdown format. Replaces full content — rich blocks created in the editor will be lost
  - `title` string — Title of the post
  - `subtitle` string — Optional subtitle or brief summary
  - `slug` string — URL-friendly identifier for the post
  - `postPreview` string — Preview text for the post
  - `categories` union — Category tags for the post. Can also be a comma-separated string.
    - string[]
    - string
  - `status` 'draft' | 'published' | 'archived' — Set to 'published' to publish, 'draft' to unpublish, or 'archived' to archive
  - `scheduledAt` integer, nullable — Unix timestamp (milliseconds) to schedule the post's first publish at a future time. Must be in the future and at most 30 days out. Only valid for draft posts that haven't been published or already scheduled. Cannot be combined with status: 'draft' or 'archived'. Pass null to cancel a previously scheduled publish.
  - `sendNewsletter` union — Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false
    - boolean
    - 'true' | 'false' | '1' | '0'
  - `publishedAt` integer — Unix timestamp (milliseconds) to set as the post's publish date. Once set, the date is preserved across re-publishes.

## Response `200`

Post updated successfully

- object
  - `success` true, required — Whether the update succeeded

## Other responses

- `400` — Invalid request - check field values
- `401` — Invalid or missing API key
- `404` — Post not found in your publication
- `500` — Internal server error

## Changes

- **2026-04-28** `79fe03bb4057` — 1 info
  - added the new optional request property `publishedAt`
- **2026-04-14** `83a575869764` — 2 info
  - added the new optional request property `scheduledAt`
  - added the new optional request property `sendNewsletter`
- **2026-03-20** `5b9472285686` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/paragraph-xyz/apis/paragraph-api/changes/v1/posts/:postId/put.md)

---

[API](https://skmtc.dev/paragraph-xyz/apis/paragraph-api.md) · [All operations](https://skmtc.dev/paragraph-xyz/apis/paragraph-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/paragraph-xyz/paragraph-api/revisions/a70bb5fa8a85/schema)
