# PostEverywhere Changelog Reference > PostEverywhere API changelog and version history. Track breaking changes, new endpoints, and improvements. **Source:** https://posteverywhere.ai/docs/changelog **Section:** Reference **API reference:** https://posteverywhere.ai/docs/api/reference --- All notable changes to the PostEverywhere API. ## 2026-08-28: Posting queue and approval workflow via API The posting queue and the approval workflow shipped in the app today, and the API surface shipped with them. All changes are **additive**: existing integrations are unaffected. ### Posting queue - **`GET /v1/queue`**: the workspace's recurring openings plus a preview of where the next posts will land (wall-clock in the queue's timezone). The preview is a forecast; allocation happens at create time. - **`POST /v1/posts` now accepts `use_queue: true`**: the server allocates the queue's next free opening and schedules the post into it. No `scheduled_for` needed (passing both returns 400). Requires a queue to exist; missing, empty, and full queues each return a distinct 400 message. - Queue **management** (editing openings) is deliberately app-only: posting cadence is a human choice, and a bot silently rewriting it is the failure mode we refuse. ### Approval workflow - **`POST /v1/posts` with `draft: true` now accepts `request_approval: true`**: the draft enters the approval workflow immediately: `approval_status` becomes `pending`, owners and admins are notified, and it appears in the app's Approvals inbox. - **`POST /v1/posts/{id}/approve`**: clears a pending post. Body: optional `{ "note": "..." }`. Approving does not publish; scheduling the cleared draft is what sends it out, and one approval authorizes exactly one publish. An API key is an organization credential (only owners and admins can mint one), so a key approving is an admin approving by proxy. - **`POST /v1/posts/{id}/request-changes`**: sends a pending post back to its author. Body: `{ "note": "..." }`, **required** (the author sees it). - **`GET /v1/posts?approval=pending|approved|changes_requested`**: filter by approval state. A separate axis from `status`: a pending post is also a draft. ### New webhook events - `post.approval_requested`, `post.approved`, `post.changes_requested`: fired from both the app and the API, so an integration hears about approvals wherever they happen. Same envelope and HMAC signature as every other event. ### MCP server - MCP tools for the queue and approvals are **deliberately held** until the ChatGPT apps directory review of the current 37-tool inventory completes, then ship together with an updated submission. ## 2026-06-14: Drafts via API & MCP: create-review-schedule for agents You can now create a post as a **draft** through the API and MCP, review it, and schedule it in a separate step. This unlocks the human-in-the-loop approval pattern: an agent drafts posts, a person (or a second agent) reviews them, and only then are they scheduled or published. All changes are **additive**: existing integrations are unaffected. ### Draft creation on `POST /v1/posts` - **`POST /v1/posts` now accepts `draft: true`**: saves the post as a draft instead of publishing or scheduling it. The response returns `status: "draft"`, the `post_id`, and a `next_steps` hint pointing at the schedule endpoint. - **`account_ids` is optional for a draft.** You can save a draft now and choose its target accounts later (either when editing the draft or in the schedule call). For a non-draft post, `account_ids` is still required. ### New endpoint: `POST /v1/posts/{id}/schedule` - **Turns a draft into a scheduled (or immediately-publishing) post.** Body: `{ "scheduled_for": "" }` to schedule, or `{ "publish_now": true }` to publish immediately. Optional `account_ids` (to set/override the draft's targets) and `timezone` (display metadata). - **Only works on drafts.** Calling it on a post that is already scheduled, publishing, or published returns **409**: re-scheduling an existing scheduled post is still done with `PATCH /v1/posts/{id}`. ### Richer drafts on `GET /v1/posts` and `GET /v1/posts/{id}` - **`GET /v1/posts?status=draft`** and **`GET /v1/posts/{id}`** now return each draft's target `account_ids` and `platform_content`, so an agent (or a reviewer) can inspect exactly what a draft will publish before scheduling it. ### MCP server - **`create_post` gains a `draft` boolean**: set `draft: true` to save a draft instead of publishing/scheduling. - **New `schedule_post` tool**: params: `post_id`, plus `scheduled_for` (ISO 8601 UTC) **or** `publish_now: true`, and optional `account_ids` and `timezone`. The full agent flow is now `create_post(draft: true)` → review with `list_posts(status: "draft")` / `get_post` → `schedule_post`. ### ChatGPT & OpenAI Codex - The hosted MCP server and the [agent docs](/docs/integrations/agents) now call out **ChatGPT** (via the hosted connector at [posteverywhere.ai/agents](https://posteverywhere.ai/agents)) and **OpenAI Codex** alongside Claude Code, Claude Desktop, and Cursor as supported AI clients. ## 2026-06-11: Major API upgrade: introspection, webhooks, campaigns, bulk ops The largest single API expansion since launch. Eleven new endpoints + a comprehensive enhancement of `GET /v1/posts`. All changes are **additive**: existing integrations continue to work unchanged. ### New endpoints - **[`GET /v1/me`](/docs/introspection)**: introspection. Returns your API key context, scopes, organization, quota (accounts/AI credits/storage), and plan limits in one call. Call this first when initializing an integration so you don't have to hardcode `organization_id`. - **[`GET /v1/analytics/summary`](/docs/analytics-summary)**: aggregate counters for a time window (today / week / month / all / custom). Returns posts-by-status, per-platform breakdown, total views/likes/comments/shares/impressions/clicks, and AI credits used. One call instead of listing every post and counting client-side. - **Campaigns CRUD** ([`GET`/`POST` `/v1/campaigns`, `GET`/`PATCH`/`DELETE` `/v1/campaigns/:id`](/docs/campaigns)): group related posts under named campaigns. Tag posts via `campaign_id` on `POST /v1/posts` and filter via `?campaign_id=…` on the list endpoint. - **[`POST /v1/posts/bulk`](/docs/bulk-operations#create-up-to-50-posts-in-one-request-post-v1postsbulk)**: create up to 50 posts in one call. Counts as ONE API-rate-limit hit instead of N. Returns per-item success/error so you can handle partial failures (HTTP 207 Multi-Status for mixed outcomes). - **[`POST /v1/posts/retry-failed`](/docs/bulk-operations#retry-every-failed-post-at-once-post-v1postsretry-failed)**: bulk retry every failed destination matching a filter (account_id, platform, date range, post_ids, max_attempts). Refuses when no filter is provided to avoid "retry the entire failure history" footguns. - **`GET /v1/accounts/:id/health`**: token expiry, last successful publish, recent failure count, `needs_reconnection` flag, `can_post` boolean, and an overall `status` (`healthy`/`warning`/`broken`). Use this BEFORE publishing to detect a dead token in advance. - **`POST /v1/accounts/:id/reconnect`**: generate a signed dashboard URL that opens the platform OAuth reconnect flow for an account. 30-minute single-use token. - **`POST /v1/ai/generate-caption`**: generate 1-5 caption variants from topic + tone + platform. Respects per-platform character limits (X: 280, Bluesky: 300, LinkedIn: 3000, IG: 2200) and hashtag conventions. Costs 1 AI credit per returned caption. - **[Webhooks](/docs/webhooks)**: `POST`/`GET` `/v1/webhooks`, `GET`/`PATCH`/`DELETE` `/v1/webhooks/:id`, `POST /v1/webhooks/:id/test`. Subscribe to event streams instead of polling. 12 event types (`post.published`, `post.failed`, `post.partially_failed`, `account.reconnect_needed`, `media.uploaded`, …). HMAC-SHA256 signing, exponential-backoff retries (30s → 2min → 10min → 1h → 6h → 24h, 6 attempts), auto-disable after 20 consecutive failures. ### Enhanced `GET /v1/posts` All new query params are optional and additive: the old single-value `?status=` and `?platform=` keep working. - **`status`** now accepts comma-separated values, and adds `failed`, `partially_failed`, `publishing` (was: only `scheduled` / `published` / `draft`). Example: `?status=failed,partially_failed`. - **`platform`** now accepts comma-separated values. Example: `?platform=instagram,tiktok`. - **`account_id`**: filter to one social account. - **`campaign_id`**: filter to a campaign. - **Date range filters:** `created_after`, `created_before`, `scheduled_after`, `scheduled_before`, `published_after`, `published_before`, `updated_after` (the last one for incremental sync polling). - **`search`**: full-text search on post content (`ILIKE`). - **`sort`**: `created_at` (default) | `scheduled_for` | `published_at` | `updated_at`. - **`order`**: `asc` | `desc` (default). - **Response includes `pagination.total` + `pagination.has_more`** so clients know if more pages exist without fetching the next one. - **Response includes per-destination `metrics`** (views/likes/comments/shares/impressions/saves/clicks) inline: no more N+1 fetch pattern. - **Response includes `campaign_id`** on each post for round-trip + filtering. ### MCP server expansion The Claude Code MCP server now exposes the new endpoints as tools: `get_me`, `get_analytics_summary`, `list_campaigns`, `create_campaign`, `get_campaign`, `update_campaign`, `delete_campaign`, `bulk_create_posts`, `retry_failed_posts`, `get_account_health`, `reconnect_account`, `generate_caption`, `list_webhooks`, `create_webhook`, `get_webhook`, `update_webhook`, `delete_webhook`, `test_webhook`, `list_posts_advanced`. Existing tools (`list_posts`, `create_post`, etc) are unchanged. ### SDK `@posteverywhere/sdk` v1.3.0 publishes companion methods: `client.getMe()`, `client.getAnalyticsSummary()`, `client.listCampaigns()`, `client.bulkCreatePosts()`, `client.retryFailedPosts()`, `client.getAccountHealth()`, `client.getAccountReconnectUrl()`, `client.generateCaption()`, `client.listWebhooks()`, `client.createWebhook()`, `client.listPostsAdvanced()`. All new methods are TypeScript-typed. ### Backwards compatibility - All previously documented params and response fields continue to work and contain the same shape. - `?status=scheduled` (single value) still works: comma-separated is opt-in. - `?platform=instagram` (single value) still works. - Old `pagination: { limit, offset }` shape unchanged; new fields (`total`, `has_more`) are added. - New response fields (`campaign_id`, `metrics`, etc) are appended; nothing was removed. - New endpoints are net-new: they don't collide with anything in v1. ## 2026-05-29: Bluesky support, accurate post status, media auto-finalize **Bluesky (AT Protocol) is now a supported platform** (the 9th). Connect a Bluesky account with a handle + app password, then publish text, images (up to 4), video (MP4), and threads. Links, `@mentions`, and `#hashtags` are turned into rich-text facets automatically, and URLs render as link cards. See the [Bluesky guide](/docs/platforms/bluesky). - **`post_status` now reflects real publishing progress.** Previously a `publish_now` post could report `scheduled` indefinitely because the value was fixed at creation time. The status is now derived from per-destination state and can be `scheduled`, `publishing`, `published`, `partially_failed`, or `failed`: consistent across `POST /v1/posts`, `GET /v1/posts/{id}`, the list endpoint, and `/results`. The `?status=` list filter now filters on the same real status. - **Posts auto-finalize uploaded media.** If you attach `media_ids` for media that was uploaded but not yet finalized with `POST /v1/media/{id}/complete`, `POST /v1/posts` now completes it for you (verifying the file exists) instead of returning `media_not_ready`. The explicit `/complete` call is still supported and recommended for tighter control. - **Clearer errors.** Posting `multipart/form-data` to `/v1/posts` now returns guidance on the correct JSON shape and the upload → `media_ids` flow. The media status response exposes `ready` and `action_required` fields so polling clients know a `/complete` call is required. ## 2026-04-12: `scheduled_for` rename, strict field validation, scope visibility **`scheduled_for` is now the canonical request field for scheduling posts.** The old name `scheduled_at` was a misnomer: it read as a past-tense timestamp (like `created_at` / `updated_at`) even though it represented a *future* moment when the post will publish. `scheduled_for` makes the intent explicit. - **`scheduled_for` is the canonical request field name** (was `scheduled_at`). The response also returns the value under `scheduled_for`, completing the round-trip. - **`scheduled_at` is deprecated but still accepted as an alias.** Existing integrations built before 2026-04-12 will continue to work unchanged. New integrations should use `scheduled_for`. - **Strict `400` validation for unknown media field names.** If you send `media`, `media_id`, `mediaId`, or `attachments` in a request body, the API now returns `400 invalid_field_name` with a helpful `did you mean media_ids?` hint. The only accepted media field on requests is `media_ids` (an array of UUID strings). - **OAuth scope visibility.** When a user reconnects a social account and the platform drops scopes from the grant, we now record the drop and alert on the mismatch, so silently-broken integrations surface quickly. - **Body logging for v1 endpoints.** The v1 API now logs sanitized request bodies (with API keys and tokens redacted) for debug visibility, making it much easier to trace bad requests when you email developer support. - **Round-trip principle.** Every top-level field name in a request body also appears in the response with the same name and meaning. You can take a post you got from `GET /v1/posts/{id}` and POST its fields straight back to clone it: no renaming. ## v1.0: March 2026 - Initial public API release - 18 endpoints across Accounts, Posts, Media, and AI - Support for 8 platforms: Instagram, TikTok, YouTube, LinkedIn, X, Facebook, Threads, Pinterest - Bulk scheduling (up to 100 posts per request) - AI image generation - MCP server integration for Claude Code - Node.js SDK --- Subscribe to API updates by emailing **developers@posteverywhere.ai**. **Resources:** - [Introduction](/docs) - [API Reference](/docs/api/reference)