---
title: "Reschedule a queued post"
method: PATCH
path: "/v1/posts/{id}"
tags: ["Posts"]
---

# Reschedule a queued post

`PATCH /v1/posts/{id}`

## Request

- Base URL: `https://api.letmepost.dev`
- URL: `https://api.letmepost.dev/v1/posts/{id}`
- Auth: HTTP bearer

Move a scheduled post to a new firing time. Only allowed when `status=queued` AND `scheduledAt` is still in the future — once a post enters `publishing` or any terminal state, the window closes and the request returns `409`.

The operation is atomic: the API replaces the BullMQ job (removes the old delayed job, enqueues a new one at the updated delay) and only persists the new `scheduledAt` if the queue swap succeeded. A `post.rescheduled` webhook fires on success, carrying both the old and new timestamps.

## Path parameters

- `id` string, required

## Request body

- object
  - `scheduledAt` string, date-time, required: ISO-8601 timestamp with timezone. Must be at least 1 second in the future.

## Response `200`

Reschedule applied; row reflects the new `scheduledAt`.

- Post: A single per-target post row from the post log.
  - `id` string, required
  - `profileId` string, required
  - `accountId` string, required
  - `account` object, required
    - `id` string, required
    - `platform` 'bluesky' | 'facebook' | 'instagram' | 'linkedin' | 'pinterest' | 'threads' | 'tiktok' | 'twitter', required: Supported platforms. `tiktok` posts upload to the creator's TikTok inbox as a draft that the creator confirms in the TikTok app; Direct Post is not implemented yet.
    - `platformAccountId` string, required
    - `displayName` string, nullable, required
  - `platform` 'bluesky' | 'facebook' | 'instagram' | 'linkedin' | 'pinterest' | 'threads' | 'tiktok' | 'twitter', required: Supported platforms. `tiktok` posts upload to the creator's TikTok inbox as a draft that the creator confirms in the TikTok app; Direct Post is not implemented yet.
  - `status` 'queued' | 'validated' | 'publishing' | 'published' | 'failed' | 'rejected' | 'canceled', required: Lifecycle state of a single per-target post row. `canceled` is the terminal state reached via `DELETE /v1/posts/{id}` on a queued scheduled post.
  - `text` string, required
  - `mediaRefs` unknown[], required
    - unknown
  - `scheduledAt` string, date-time, nullable, required
  - `publishedAt` string, date-time, nullable, required
  - `platformUri` string, nullable, required
  - `platformCid` string, nullable, required
  - `error` unknown
  - `createdAt` string, date-time, required
  - `updatedAt` string, date-time, required

## Other responses

- `400`: `validation_failed` — request body or query parameters didn't match the schema. Rules surfaced include `body.json`, `targets.required`, `targets.max`, `mode_conflict`, `targets.options.platform_mismatch`, `targets.account.platform_mismatch`, `target.account.not_connected`, `target.account.ambiguous`, `scheduledAt.future`, `scheduledAt.no_first_comment`, `scheduledAt.no_bluesky_reply`.
- `401`: `unauthenticated` — missing or invalid Bearer key.
- `404`: `not_found` — the resource does not exist in the caller's organization (or, for profile-scoped keys, in the caller's profile).
- `409`: Post is no longer in the modifiable window (status != `queued` or `scheduledAt` already passed). Error rule: `post.status` or `post.scheduledAt.window`.
- `429`: `rate_limited` — too many requests. Inspect `X-RateLimit-Limit` (static ceiling) and the IETF-draft `RateLimit-*` headers (sliding-window remaining/reset) before retrying.

---

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