# Changelog (/docs/changelog)



2026-11-06 [#2026-11-06]

Docs generated from the code [#docs-generated-from-the-code]

* Platform limits on every platform page and in [Platform Support](/docs/platforms/overview) now come straight from the rules the API checks posts against.
* The error codes in [Errors](/docs/api/errors) come from one catalog in the code; a test fails when the API answers with a code the docs do not list. `tiktok_privacy_not_allowed` was listed as a check before storing, but it happens while publishing and comes back as `platform_rejected`; it is no longer listed there.
* New [MCP tool reference](/docs/mcp/tools) with every tool, its parameters and the scope it needs.

Publishing errors you can act on [#publishing-errors-you-can-act-on]

* `targets[].error` now has `code`, `category` and `source` besides `message`. `source` says who can fix it: `user`, `platform` or `system`. New codes `platform_rejected`, `platform_auth_failed`, `platform_rate_limited` and `platform_unavailable` replace most `publish_failed`. See [Publishing errors](/docs/api/errors#publishing-errors).
* Only rate limits and outages are retried automatically. A post the platform refused is no longer sent again twice.
* New webhooks `post.target.published` and `post.target.failed`, sent per account as soon as it is done. See [Webhooks](/docs/guides/webhooks#event-data).
* The `targets` in `post.published`, `post.partial` and `post.failed` now carry `targetId`, `accountId`, `platformUrl` and the structured `error`.
* Bluesky, Pinterest and TikTok refusals (an image over 1 MB, no board, a video TikTok's checks rejected) now fail at once with `platform_rejected` instead of being retried.

New docs structure [#new-docs-structure]

* The docs have sections for getting started, concepts, guides, platforms, the MCP server and the API reference. New pages: [Data model](/docs/concepts/data-model) and [API basics](/docs/api).
* Endpoint pages have readable URLs, for example [/docs/api/posts/create](/docs/api/posts/create). Authentication, errors, rate limits, idempotency and pagination moved to the API reference, the MCP guide to [/docs/mcp](/docs/mcp). Old URLs redirect.
* `error.docUrl` points to [/docs/api/errors](/docs/api/errors).

2026-11-05 [#2026-11-05]

API and docs fixes [#api-and-docs-fixes]

* Every entry in `error.details` of a failed post check now carries its own `code`, such as `content_too_long`, so you can branch on each problem. With several problems `error.code` is `post_invalid`.
* [Error handling](/docs/api/errors) lists every code the API returns, including media and post-check codes, and a new section on publishing errors in `targets[].error`.
* Corrected platform limits: LinkedIn takes one file per post (JPEG, PNG, GIF, MP4 or PDF) and posts to personal profiles only; Instagram takes JPEG, PNG and MP4. See [Platform Support](/docs/platforms/overview).
* Disconnecting an account deletes its scheduled posts; the docs now say so.
* Connect links can be created with the API and need no FeedHorizon login. See [Connect links](/docs/guides/connect-links).
* Unknown docs pages answer 404 instead of 500.
* Instagram posts now link to their real permalink in `platformUrl`. Before, the link used the media id and did not open the post.

TikTok (beta) [#tiktok-beta]

* Publish and schedule TikTok videos (MP4, MOV or WebM) with a caption of up to 2,200 characters. Accounts connect with TikTok sign-in.
* Every TikTok post needs `options.tiktok.privacyLevel`, chosen by the poster from the account's allowed levels. Comments, duets and stitches are off unless allowed, and `brandOrganic` / `brandedContent` disclose commercial content. New validation errors `tiktok_privacy_required` and `tiktok_branded_content_private`.
* New endpoint `GET /v1/accounts/{id}/tiktok-creator` and MCP tool `get_tiktok_creator`.
* Until TikTok has reviewed FeedHorizon, videos are published as private. See [TikTok](/docs/platforms/tiktok).

Pinterest [#pinterest]

* Publish and schedule Pins: one image, or 2 to 5 images as a carousel, with a description of up to 500 characters. Accounts connect with Pinterest sign-in and stay connected through automatic token renewal.
* New per-account `options` on post targets. For Pinterest: `options.pinterest.boardId`, `title` and `link`. Without a board the Pin goes to the account's first board.
* New endpoint `GET /v1/accounts/{id}/boards` and MCP tool `list_pinterest_boards`. See [Pinterest](/docs/platforms/pinterest).

Bluesky [#bluesky]

* Publish and schedule Bluesky posts: text up to 300 characters, up to 4 images (1 MB each), links, hashtags and mentions as rich text. Accounts connect with an app password through the dashboard or a connect link. See [Bluesky](/docs/platforms/bluesky).
* New validation error `media_too_large` when a file exceeds a platform's size limit.

Accounts stay connected [#accounts-stay-connected]

* Instagram connections are renewed automatically before their 60 days run out. LinkedIn connections are renewed where LinkedIn issues refresh tokens.
* New webhook `account.expiring`, sent 7 days before a connection ends that cannot be renewed, and `account.needs_reauth`, sent once a connection stopped working. The person who connected the account gets an email in both cases. See [Webhooks](/docs/guides/webhooks).
* Accounts in the API have a new field `tokenExpiresAt`.
* In the dashboard, an account that needs a reconnect shows a **Reconnect** button.

2026-11-04 [#2026-11-04]

MCP server [#mcp-server]

* AI assistants such as Claude and ChatGPT can connect at `https://feedhorizon.com/mcp`, with OAuth sign-in or an API key. 18 tools cover posts, queues, media and connect links. See [MCP Server](/docs/mcp).
* **API & Apps** in the dashboard lists the connected apps of the organization and disconnects them.

API [#api]

Breaking changes, all at once, so that everything after this builds on one consistent base:

* Errors have one shape everywhere: `{ "error": { "type", "code", "message", "param", "details", "docUrl", "requestId" } }`. Branch on `type` and `code`, never on `message`. See [Error handling](/docs/api/errors).
* Lists return `{ "data", "nextCursor" }` and page with `cursor` and `limit` (1 to 100, default 20). The `meta` object with `page`, `perPage` and `total` is gone. See [Pagination](/docs/api/pagination).
* Statuses are lowercase, for example `published` and `partially_failed`.
* Objects in profiles your key cannot access now answer `404` instead of `403`.
* Webhook signatures include a timestamp: `X-Webhook-Signature: t=<unix>,v1=<hex>`, signed over `<t>.<body>`. Every event has an `id`, also sent as `X-Webhook-Id`. See [Webhooks](/docs/guides/webhooks).
* The events `message.received` and `comment.received` were removed. They were never sent.
* The `mediaUrls` field on posts was removed. Use `mediaIds` instead, see [Media uploads](/docs/guides/media-uploads).

New:

* `Idempotency-Key` header on every write. A retry with the same key within 24 hours returns the first response. See [Idempotency](/docs/api/idempotency).
* Rate limits per API key by plan, shared across all servers, with `X-RateLimit-*` and `Retry-After` headers. See [Rate limits](/docs/api/rate-limits).
* Every response carries `x-request-id`.
* The API reference and [/openapi.json](/openapi.json) are generated from the code that serves the API, so they cannot drift apart.
* `GET /api/v1/me` returns the organization, plan, rate limit and the calling key with its scopes. Use it to check a key.
* `GET /api/v1/platforms` lists every platform with text length, media limits and whether it is available yet.
* Profiles can carry your own id in `externalId`, unique per organization. Filter with `GET /api/v1/profiles?externalId=…`.
* API keys have a list of `scopes`, such as `posts:write`. `permission` stays as a shorthand. See [Authentication](/docs/api/authentication#scopes).
* Posts take `targets`: the accounts to publish to, each with optional own text. Every target in a response shows its `content` (null when it uses the post text). See [Scheduling](/docs/guides/scheduling#own-text-per-account).
* Posts are checked against each platform before they are stored (text length, media, schedule). All problems come back at once in `error.details`. `POST /api/v1/posts/validate` runs the same checks as a dry run.
* `POST /api/v1/posts/{id}/publish`, `/cancel` and `/duplicate`.
* `GET /api/v1/posts?updatedSince=…` for syncing.
* Queue endpoints: `GET` and `PUT /api/v1/profiles/{id}/queue`, `GET /api/v1/profiles/{id}/queue/slots`. See [Scheduling](/docs/guides/scheduling#the-queue).
* Media through the API: `POST /api/v1/media` imports a file from a URL or returns a direct upload link, and `mediaIds` attaches files to posts. See [Media uploads](/docs/guides/media-uploads).

2026-03-09 [#2026-03-09]

Docs [#docs]

* Clustered docs navigation into Guides, Platforms and API Reference
* Added new Guides pages for Scheduling and Webhooks
* Expanded Platforms section with coming-soon platform pages
* Added top-level Pricing and Changelog docs pages
* Added Resources section in docs sidebar

2026-03-07 [#2026-03-07]

Integrations [#integrations]

* Added Instagram OAuth connect flow and callback handling
* Added invite-token state support for delegated account linking

Documentation [#documentation]

* Added Instagram platform guide and SaaS setup checklist
* Updated architecture and roadmap documentation

2026-03-01 [#2026-03-01]

API [#api-1]

* Added API key management endpoints and dashboard UI
* Added webhook CRUD and test delivery endpoints
* Added rate limiting headers and enforcement

Platform invites [#platform-invites]

* Added invitation links for delegated platform connections
* Added invite landing page and single-use token flow
