API Changelog and Deprecation Ledger
This page records externally relevant REST and MCP contract changes. Dates are deployment or documentation publication dates, not announcement estimates.
Upcoming
2026-08-25 — scheduledTime strict-mode ramp
- Affected surface: REST
create-postandupdate-post, plus MCP tools that schedule through them. - Tag: Potentially breaking, configuration-dependent.
- Change: A
scheduledTimeat least five minutes in the past is scheduled to return400 SCHEDULED_TIME_IN_PASTstarting on 2026-08-25. This calendar behavior applies only when production configuration does not explicitly override it withSCHEDULED_TIME_STRICT; an explicit flag wins in either direction. - Migration action: Always send a future ISO 8601 UTC time. During the warn-first period, inspect
warnings[].code === "SCHEDULED_TIME_COERCED"and the returnedscheduledTimeto find callers that need correction.
2026-08-27
Native Zapier app (beta)
- Affected surface: No REST or MCP contract change. Publora now has a native app on Zapier (beta, v1.2.0), built on the public API and webhooks: instant triggers New Published Post and New Scheduled Post, actions Create Post, Update Post and Delete Post, and searches Find Connected Account and Find Posts.
- Tag: Additive.
- Change: The Zapier guide was rewritten for the native app. It previously documented a workaround through Webhooks by Zapier; that approach still works and stays documented on the same page for endpoints the app does not expose.
- Migration action: None. Existing Webhooks-by-Zapier Zaps keep working; the native app is the recommended path for new Zaps.
2026-08-24
Connection health reporting corrected — publora.com #407
- Affected surface: REST
GET /platform-connectionsand the MCPlist_connectionstool, which passes that response through unchanged.test-connectionreports the same corrected expiry. - Tag: Behavioral correction. No request shape changes, no field is added or removed; two response fields now report different — and correct — values for some connections.
- Changes:
accessTokenExpiresAtnow carries the effective credential expiry, the same valuetokenStatusandtokenExpiresInare derived from, instead of the raw stored access-token timestamp. For YouTube it is now alwaysnull: the access token is refreshed on demand before each publish, and Google publishes no refresh-token lifetime, so no authoritative date exists. TikTok continues to report its real refresh-token expiry; every other platform is unchanged.- Previously, healthy YouTube and TikTok connections returned a timestamp already in the past alongside
tokenStatus: "valid". Clients that compared that date against the current time concluded the connection was dead and prompted users to reconnect working channels. tokenStatusnow returnsexpiredfor any connection Publora has flagged for reconnection after the platform rejected its credential — including on platforms that never expire on a schedule, where such a connection previously reportedvalid. In that caseaccessTokenExpiresAtmay benullor still in the future.
- Migration action: Decide about reconnecting from
tokenStatus, not by comparingaccessTokenExpiresAtagainst the clock. Treatexpiredas "prompt the user to reconnect" andexpiring_soonas "warn". Treat anullexpiry as "no scheduled expiry", never as a problem. The examples on the endpoint, guide and MCP pages were rewritten accordingly; code copied from earlier versions of those examples should be updated.
X replies and quote posts — publora.com #405
- Affected surface: REST
create-postandupdate-post, the MCPcreate_postandupdate_posttools, and theposts[].error.codereported byGET /get-postand thepost.failedwebhook. - Tag: Additive. No existing request shape changes behavior.
- Changes:
platformSettingsaccepts a new top-leveltwitterobject with two string keys,replyToandquoteTweet. Both take a fullx.com/twitter.comstatus URL or a bare 1–19 digit post ID, and both are normalized to the numeric ID before storage, soGET /get-postechoes the ID rather than the URL you sent.replyTopublishes the post — or the head part of a thread — as a reply to the target; the remaining thread parts chain under it as before.quoteTweetapplies to the single post or the thread head only. The two fields combine with each other and with media. An empty string clears either one.- A malformed reference is rejected at intake with
400and a plainerrormessage (platformSettings.twitter.replyTo must be a tweet URL (https://x.com/user/status/123...) or a numeric tweet ID); nocodefield accompanies it. An unknown key undertwitteris still400 PLATFORM_SETTING_UNKNOWN, which is evaluated first. - Two publish-time codes were added:
X_REPLY_NOT_AUTHORIZEDwhen X refuses the reply or quote relationship, andX_TARGET_REJECTEDwhen the target is deleted, protected, or its author blocked the account. Both are permanent —retryable: false. twitteris no longer an example of a rejectedplatformSettingsplatform; the allowlist now has seven platforms.
- Restriction to know before integrating: X allows a programmatic reply or quote on self-serve API tiers only when the target post's author mentioned the connected account in that same post, quoted one of the account's posts, or the connected account authored the target. Enterprise apps are exempt. Publora cannot check that relationship at intake, so an unrelated target is accepted by
create-post/update-postand fails later at publish time. - Migration action: None for existing callers. New integrations should treat these fields as inbound-engagement and own-post tools, match on
error.coderather than message text, and not retryX_REPLY_NOT_AUTHORIZEDorX_TARGET_REJECTEDwith the same target.
2026-08-03
MCP OAuth consent no longer asks for an API key
- Affected surface: the OAuth 2.1 flow on
mcp.publora.com(Dynamic Client Registration + PKCE), used by claude.ai's custom connector, Claude Code, Codex/ChatGPT, Cursor, VS Code, Manus and other browser-capable clients. - Tag: Behavioral, non-breaking for existing credentials.
- Change: The consent step is a sign-in-and-approve page — "An application is requesting access to your Publora account", naming the account being authorized, with Approve and Cancel. It no longer asks you to paste an
sk_...key; that step was replaced when SSO login shipped on 2026-07-27, and the wording was finalized on 2026-08-03. On approval Publora mints a dedicated API key for that client registration, namedMCP (<client> #<id>), and returns it as the access token. Static API-key headers (Authorization: Bearer sk_.../x-publora-key) are unaffected and remain the option for headless clients. - Migration action: None for connectors that already work. Re-authorizing a client mints a fresh key; per-client keys are listed and revocable on the API page in the dashboard. If you built on the old instructions and expected a key-paste page, drop that step.
2026-07-21
Editable draft and scheduled posts — publora.com #231
- Affected surface: REST
PUT /update-post/:postGroupIdand the MCPupdate_posttool. - Tag: Additive, with new stable conflict codes.
- Changes:
update-postaccepts two new optional patch fields:content(replacement base text) andplatforms(replacement target set). Omitting a field leaves the stored value unchanged.- A
contentedit rewrites every platform post to its effective text while preserving explicit per-account overrides; editing the text of a Twitter or Threads target clears its derived thread split. - A
platformsedit replaces the whole target set: dropped IDs have their platform posts deleted, added IDs are validated for ownership and plan entitlement, and adding a target to a scheduled post re-runs scheduling limits plus full content/media validation.[]is accepted only while the post remains a draft. - Added stable codes
POST_NOT_EDITABLE(400),POST_PUBLISH_IN_PROGRESS(409), andPOST_GROUP_VERSION_CONFLICT(409), plusINVALID_CONTENT,INVALID_PLATFORMS,INVALID_PLATFORM_CONNECTION, andINVALID_PLATFORM_ID(400). The pre-existing"Cannot update post: post is currently in {status} status"400 now also carriescode: "POST_NOT_EDITABLE". - The success snapshot's
postGroupnow always includes the effectivecontentandplatforms. - The "at least one field" error text changed to
"At least one of status, scheduledTime, content, platforms, platformSettings, or mediaUrls must be provided". platformsarrays on bothcreate-postandupdate-postnow reject duplicate connection IDs with400 "Platforms must not contain duplicates".- MCP
update_postexposescontentandplatforms, and instructs clients to calllist_connectionsbefore changing targets.
- Migration action: No change is required for existing callers. Integrations that previously deleted and recreated a post to fix its text or targets should switch to
update-post. Match on the newcodevalues rather than message text, send anIdempotency-Keywith content/platform edits, and re-read the post withGET /get-poston a 409 instead of blind-retrying. If you relied on a repeated connection ID inplatformsbeing tolerated, de-duplicate the array.
2026-07-15
API/MCP correctness release — publora.com #198
- Affected surface: REST create/update/get-post, webhooks, MCP sessions and tool responses.
- Tags: Breaking for unknown
platformSettingspaths; additive/behavioral for the remaining items. - Changes:
- Added Mongo-backed
Idempotency-Keyhandling to create/update. - Added the warn-first
scheduledTimeramp and structured coercion/rejection codes. - Unknown
platformSettingspaths now return400 PLATFORM_SETTING_UNKNOWN; they are no longer silently discarded. - Added MCP session admission checks and more robust MCP response parsing.
- Publication identity now flows through get-post and
post.published, includingplatformId,postedId, and nullablepermalink.
- Added Mongo-backed
- Migration action: Remove unknown settings before retrying; add idempotency keys to retryable create/update workflows; read publication identity from documented fields; audit past-time warnings before strict mode.
LinkedIn repost/reshare — publora.com #194
- Affected surface: REST, MCP, and scheduled LinkedIn publishing.
- Tag: Additive.
- Changes: Added
POST /linkedin-reshare, thelinkedin_create_reshareMCP tool (the 14th active tool), andplatformSettings.linkedinwithrepostEnabled,repostParentUrn, andrepostVisibilityas the sixth accepted settings branch. - Migration action: No change is required for existing callers. New integrations should use a
urn:li:share:*orurn:li:ugcPost:*parent.CONNECTIONSvisibility is personal-profile-only; usePUBLICfor company-page reposts.
Correctness-release documentation — publora-api-docs #21
- Affected surface: Public API, MCP, webhook, and OpenAPI documentation.
- Tag: Documentation.
- Change: Published the idempotency, scheduled-time, strict-settings, MCP-draft, and publication-identity contract introduced by the correctness release.
- Migration action: Compare existing integrations with the updated create/update, get-post, webhook, and MCP reference pages; no separate runtime change was introduced by the docs release.
Deprecation policy
No additional public API deprecations are currently scheduled. Future entries will identify the affected surface, breaking behavior, effective date, and migration action.