Skip to content

Content API

REST endpoints for the Content area of Lepsto.

The Content area publishes 42 REST endpoints. Paths are relative to https://api.lepsto.com; see Authentication for the required header.

GET/content/channels

List the channels this product can publish to, with each one's limits and per-post cost. A LinkedIn profile, X or YouTube account connected on the Integrations page appears here by itself as an auto channel named after the account (origin integration). The seeded channels, one per network, use reminder delivery: the system prepares the post and notifies a person to publish it. Every channel is returned, on or off: enabled says whether it is in use (integration channels always are; a new product starts with every seeded channel off), and only a channel with enabled true can be scheduled. Label a network with networkName, never with a channel's displayName.

MCP tool: content_channels_list

Parameters

NameInTypeRequiredDescription
networkquery
stringone of: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky, telegram
—
Return only channels on this network.
limitquery
integer
—
Maximum number of channels to return (1-100, default 50).
offsetquery
integer
—
How many channels to skip, for paging.

Response

Returns object.

FieldTypeAlwaysDescription
total
integer
•
Total number of matching channels, ignoring paging.
channels
object[]
•
The page of channels, ordered by network.
GET/content/channels/:id

Read one channel: its delivery mode and its capability descriptor — the character limit, media rules and cost to check before composing a variant for it.

MCP tool: content_channels_get

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The channel id returned by content_channels_list.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Channel id — pass this to content_publications_schedule.
origin
stringone of: integration, manual
—
integration: the channel appeared by itself from an account connected on the Integrations page. manual: a seeded channel, or one bound by hand.
enabled
boolean
•
Whether this channel is in use. An integration channel is always true. A manual channel is true once someone turns it on with content_channels_update (a new product starts with every manual channel off). Nothing can be scheduled on a channel that is off: content_publications_schedule refuses it with channel_disabled.
network
string
•
Social network: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky or telegram.
pausedAt
string | null
•
ISO-8601 time the connector stopped working, or null when healthy. A paused channel keeps its scheduled publications — they are frozen, not cancelled, and dispatch once it resumes.
createdAt
string
•
ISO-8601 creation time.
updatedAt
string
•
ISO-8601 time of the last change.
connectorId
string | null
•
Platform connector this channel publishes through, or null for a reminder channel that needs none. An id — this toolkit never holds social credentials; a token is fetched per call and discarded.
displayName
string
•
Human label for the channel.
networkName
string
•
The network as a person names it — LinkedIn, X, YouTube. Use it to label a network; displayName is the account or channel name.
pauseReason
string | null
•
Why it paused: revoked (access was taken away), expired (the credential ran out), detached (the integration was detached from this product), removed (the integration was deleted), or the provider reason code from a failed publish. Null when healthy.
subjectType
stringone of: member, organization
•
Who publishes: member (a personal account) or organization (a company page). Phase 1 channels are all member accounts.
capabilities
object
•
What the channel accepts and what it costs: maxTextLength, maxMedia, supportsVideo, supportsLink, costPerPostUsd, costPerLinkPostUsd, dailyPostCeiling, ceilingIsRuntimeData, acceptsCover (whether the cover of an output is set on the network automatically — the YouTube thumbnail) and coverMaxBytes (the largest cover it takes, or null). Read maxTextLength before writing a per-channel text variant.
deliveryMode
stringone of: auto, reminder
•
How the post reaches the network: auto (this API publishes it) or reminder (the system prepares it and notifies a person, who publishes by hand). Every seeded channel is reminder.
PATCH/content/channels/:id

Rename a channel, change its delivery mode, turn a manual channel on or off (enabled), or correct its capability descriptor. Turning off is refused with 409 channel_not_toggleable for an integration channel, which is always on, and with 409 channel_has_scheduled while the channel still has publications waiting to go out — cancel them first. Channels are not created with a tool: every product starts with one per network, and each account connected on the Integrations page adds its own.

MCP tool: content_channels_update

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The channel id returned by content_channels_list.
displayNamebody
string
—
New human label for the channel. Omit to keep the current one.
deliveryModebody
stringone of: auto, reminder
—
Change how the post reaches the network. Only reminder can be scheduled in this release — no publishing adapter exists yet.
enabledbody
boolean
—
Turn a manual channel on (true) or off (false). Integration channels are always on: false is refused with channel_not_toggleable. A channel with publications still scheduled cannot be turned off: the call is refused with channel_has_scheduled until they are cancelled or have gone out. Omit to leave it as it is.
capabilitiesbody
object
—
Override individual capability fields — a known ceiling beats the hand-filled constant. Merges over the existing descriptor; fields you omit keep their current values.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Channel id — pass this to content_publications_schedule.
origin
stringone of: integration, manual
—
integration: the channel appeared by itself from an account connected on the Integrations page. manual: a seeded channel, or one bound by hand.
enabled
boolean
•
Whether this channel is in use. An integration channel is always true. A manual channel is true once someone turns it on with content_channels_update (a new product starts with every manual channel off). Nothing can be scheduled on a channel that is off: content_publications_schedule refuses it with channel_disabled.
network
string
•
Social network: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky or telegram.
pausedAt
string | null
•
ISO-8601 time the connector stopped working, or null when healthy. A paused channel keeps its scheduled publications — they are frozen, not cancelled, and dispatch once it resumes.
createdAt
string
•
ISO-8601 creation time.
updatedAt
string
•
ISO-8601 time of the last change.
connectorId
string | null
•
Platform connector this channel publishes through, or null for a reminder channel that needs none. An id — this toolkit never holds social credentials; a token is fetched per call and discarded.
displayName
string
•
Human label for the channel.
networkName
string
•
The network as a person names it — LinkedIn, X, YouTube. Use it to label a network; displayName is the account or channel name.
pauseReason
string | null
•
Why it paused: revoked (access was taken away), expired (the credential ran out), detached (the integration was detached from this product), removed (the integration was deleted), or the provider reason code from a failed publish. Null when healthy.
subjectType
stringone of: member, organization
•
Who publishes: member (a personal account) or organization (a company page). Phase 1 channels are all member accounts.
capabilities
object
•
What the channel accepts and what it costs: maxTextLength, maxMedia, supportsVideo, supportsLink, costPerPostUsd, costPerLinkPostUsd, dailyPostCeiling, ceilingIsRuntimeData, acceptsCover (whether the cover of an output is set on the network automatically — the YouTube thumbnail) and coverMaxBytes (the largest cover it takes, or null). Read maxTextLength before writing a per-channel text variant.
deliveryMode
stringone of: auto, reminder
•
How the post reaches the network: auto (this API publishes it) or reminder (the system prepares it and notifies a person, who publishes by hand). Every seeded channel is reminder.
POST/content/channels/:id/bind

Bind a channel to a platform connector by hand. For manual cases only: an account connected on the Integrations page already has its own channel. The connector must be attached to this product, match the channel's network and have no other channel in this product (connector_not_found, connector_network_mismatch, connector_already_bound otherwise). Clears an existing pause and turns the channel on. Pass deliveryMode "auto" to also switch the channel to automatic publishing; binding alone never does.

MCP tool: content_channels_bind

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The channel id returned by content_channels_list.
connectorIdbody
string (uuid)
•
The platform connector to publish through — the id of a connector attached to this product. It must be attached and of this channel's network, and not already carried by another channel of this product, or the call is refused with connector_not_found, connector_network_mismatch or connector_already_bound. Networks with no publishing connector (instagram, facebook, tiktok, threads, pinterest, bluesky, telegram, LinkedIn company pages) are refused with no_api_provider.
deliveryModebody
stringone of: auto, reminder
—
Pass auto to make this API publish through the connector. Omit to keep the current mode: binding alone never switches a channel to automatic publishing.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Channel id — pass this to content_publications_schedule.
origin
stringone of: integration, manual
—
integration: the channel appeared by itself from an account connected on the Integrations page. manual: a seeded channel, or one bound by hand.
enabled
boolean
•
Whether this channel is in use. An integration channel is always true. A manual channel is true once someone turns it on with content_channels_update (a new product starts with every manual channel off). Nothing can be scheduled on a channel that is off: content_publications_schedule refuses it with channel_disabled.
network
string
•
Social network: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky or telegram.
pausedAt
string | null
•
ISO-8601 time the connector stopped working, or null when healthy. A paused channel keeps its scheduled publications — they are frozen, not cancelled, and dispatch once it resumes.
createdAt
string
•
ISO-8601 creation time.
updatedAt
string
•
ISO-8601 time of the last change.
connectorId
string | null
•
Platform connector this channel publishes through, or null for a reminder channel that needs none. An id — this toolkit never holds social credentials; a token is fetched per call and discarded.
displayName
string
•
Human label for the channel.
networkName
string
•
The network as a person names it — LinkedIn, X, YouTube. Use it to label a network; displayName is the account or channel name.
pauseReason
string | null
•
Why it paused: revoked (access was taken away), expired (the credential ran out), detached (the integration was detached from this product), removed (the integration was deleted), or the provider reason code from a failed publish. Null when healthy.
subjectType
stringone of: member, organization
•
Who publishes: member (a personal account) or organization (a company page). Phase 1 channels are all member accounts.
capabilities
object
•
What the channel accepts and what it costs: maxTextLength, maxMedia, supportsVideo, supportsLink, costPerPostUsd, costPerLinkPostUsd, dailyPostCeiling, ceilingIsRuntimeData, acceptsCover (whether the cover of an output is set on the network automatically — the YouTube thumbnail) and coverMaxBytes (the largest cover it takes, or null). Read maxTextLength before writing a per-channel text variant.
deliveryMode
stringone of: auto, reminder
•
How the post reaches the network: auto (this API publishes it) or reminder (the system prepares it and notifies a person, who publishes by hand). Every seeded channel is reminder.
POST/content/channels/:id/resume

Resume a paused channel once its connection works again. Its frozen publications dispatch on the next scheduler tick — late, not cancelled. A channel paused as detached or removed resumes only after its integration is attached to this product again on the Integrations page; otherwise the call is refused with connector_detached. Reconnecting never resumes a channel by itself.

MCP tool: content_channels_resume

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The paused channel to resume, once its connector has been reconnected.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Channel id — pass this to content_publications_schedule.
origin
stringone of: integration, manual
—
integration: the channel appeared by itself from an account connected on the Integrations page. manual: a seeded channel, or one bound by hand.
enabled
boolean
•
Whether this channel is in use. An integration channel is always true. A manual channel is true once someone turns it on with content_channels_update (a new product starts with every manual channel off). Nothing can be scheduled on a channel that is off: content_publications_schedule refuses it with channel_disabled.
network
string
•
Social network: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky or telegram.
pausedAt
string | null
•
ISO-8601 time the connector stopped working, or null when healthy. A paused channel keeps its scheduled publications — they are frozen, not cancelled, and dispatch once it resumes.
createdAt
string
•
ISO-8601 creation time.
updatedAt
string
•
ISO-8601 time of the last change.
connectorId
string | null
•
Platform connector this channel publishes through, or null for a reminder channel that needs none. An id — this toolkit never holds social credentials; a token is fetched per call and discarded.
displayName
string
•
Human label for the channel.
networkName
string
•
The network as a person names it — LinkedIn, X, YouTube. Use it to label a network; displayName is the account or channel name.
pauseReason
string | null
•
Why it paused: revoked (access was taken away), expired (the credential ran out), detached (the integration was detached from this product), removed (the integration was deleted), or the provider reason code from a failed publish. Null when healthy.
subjectType
stringone of: member, organization
•
Who publishes: member (a personal account) or organization (a company page). Phase 1 channels are all member accounts.
capabilities
object
•
What the channel accepts and what it costs: maxTextLength, maxMedia, supportsVideo, supportsLink, costPerPostUsd, costPerLinkPostUsd, dailyPostCeiling, ceilingIsRuntimeData, acceptsCover (whether the cover of an output is set on the network automatically — the YouTube thumbnail) and coverMaxBytes (the largest cover it takes, or null). Read maxTextLength before writing a per-channel text variant.
deliveryMode
stringone of: auto, reminder
•
How the post reaches the network: auto (this API publishes it) or reminder (the system prepares it and notifies a person, who publishes by hand). Every seeded channel is reminder.
POST/content/channels/:id/unbind

Detach a channel from its platform connector, and clear any pause. Delivery mode is left as it is: an auto channel left without a connection fails its publications visibly rather than being silently downgraded to reminders. The account is not brought back as a new channel by itself: bind it again to undo.

MCP tool: content_channels_unbind

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The channel id returned by content_channels_list.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Channel id — pass this to content_publications_schedule.
origin
stringone of: integration, manual
—
integration: the channel appeared by itself from an account connected on the Integrations page. manual: a seeded channel, or one bound by hand.
enabled
boolean
•
Whether this channel is in use. An integration channel is always true. A manual channel is true once someone turns it on with content_channels_update (a new product starts with every manual channel off). Nothing can be scheduled on a channel that is off: content_publications_schedule refuses it with channel_disabled.
network
string
•
Social network: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky or telegram.
pausedAt
string | null
•
ISO-8601 time the connector stopped working, or null when healthy. A paused channel keeps its scheduled publications — they are frozen, not cancelled, and dispatch once it resumes.
createdAt
string
•
ISO-8601 creation time.
updatedAt
string
•
ISO-8601 time of the last change.
connectorId
string | null
•
Platform connector this channel publishes through, or null for a reminder channel that needs none. An id — this toolkit never holds social credentials; a token is fetched per call and discarded.
displayName
string
•
Human label for the channel.
networkName
string
•
The network as a person names it — LinkedIn, X, YouTube. Use it to label a network; displayName is the account or channel name.
pauseReason
string | null
•
Why it paused: revoked (access was taken away), expired (the credential ran out), detached (the integration was detached from this product), removed (the integration was deleted), or the provider reason code from a failed publish. Null when healthy.
subjectType
stringone of: member, organization
•
Who publishes: member (a personal account) or organization (a company page). Phase 1 channels are all member accounts.
capabilities
object
•
What the channel accepts and what it costs: maxTextLength, maxMedia, supportsVideo, supportsLink, costPerPostUsd, costPerLinkPostUsd, dailyPostCeiling, ceilingIsRuntimeData, acceptsCover (whether the cover of an output is set on the network automatically — the YouTube thumbnail) and coverMaxBytes (the largest cover it takes, or null). Read maxTextLength before writing a per-channel text variant.
deliveryMode
stringone of: auto, reminder
•
How the post reaches the network: auto (this API publishes it) or reminder (the system prepares it and notifies a person, who publishes by hand). Every seeded channel is reminder.
GET/content/folders

List this product’s folder tree as a flat array with parentId and sibling position. counts are direct posts; totalCounts include every descendant, grouped by post status.

MCP tool: content_folders_list

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
folders
object[]
•
Flat folder tree; parentId and position describe the hierarchy and order.
POST/content/folders

Create a folder at the root or inside another folder, placing it last among siblings. The parent must belong to this product; use content_folders_list to find its id.

MCP tool: content_folders_create

Parameters

NameInTypeRequiredDescription
namebody
string
•
The folder name, from 1 to 200 characters.
parentIdbody
string (uuid) | null
—
Parent folder id, or null for a root folder. New folders go last among siblings.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Folder id.
name
string
•
Folder name.
parentId
string (uuid) | null
•
Parent folder id, or null at the root.
position
integer
•
Order among siblings with the same parent.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
DELETE/content/folders/:folderId

Delete an empty folder. A folder with posts or subfolders is refused as folder_not_empty; move or delete its contents first.

MCP tool: content_folders_delete

Parameters

NameInTypeRequiredDescription
folderIdpath
string (uuid)
•
A folder id from content_folders_list or content_folders_create.

Response

Returns object.

FieldTypeAlwaysDescription
deleted
booleanone of: true
•
True when this empty folder was deleted.
folderId
string (uuid)
•
A folder id from content_folders_list or content_folders_create.
PATCH/content/folders/:folderId

Rename, re-parent or reorder a folder. beforeFolderId must be a sibling under the target parent. A move into itself or a descendant is refused as folder_cycle; use content_folders_list to inspect the tree first.

MCP tool: content_folders_update

Parameters

NameInTypeRequiredDescription
folderIdpath
string (uuid)
•
A folder id from content_folders_list or content_folders_create.
namebody
string
—
New folder name. Omit to keep it.
parentIdbody
string (uuid) | null
—
New parent folder id, or null to move to the root. Omit to keep the current parent.
beforeFolderIdbody
string (uuid) | null
—
Insert before this sibling in the target parent. Omit or set null to put the folder last.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Folder id.
name
string
•
Folder name.
parentId
string (uuid) | null
•
Parent folder id, or null at the root.
position
integer
•
Order among siblings with the same parent.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
GET/content/media

List media assets, newest first. Supply status to filter by storage status; omit it to include all statuses.

MCP tool: content_media_list

Parameters

NameInTypeRequiredDescription
statusquery
stringone of: pending, ready, failed
—
Return only assets in this storage status.
limitquery
integer
—
Maximum number of assets to return (1-100, default 50).
offsetquery
integer
—
How many assets to skip, for paging.

Response

Returns object.

FieldTypeAlwaysDescription
total
integer
•
Total number of matching assets, ignoring paging.
assets
object[]
•
The page of assets, newest first.
POST/content/media

Ingest media from a public http(s) URL: the toolkit fetches it and stores it in the product bucket. Images and video up to 512 MB. A fetch that fails returns the asset with status "failed" and a reason rather than an error.

MCP tool: content_media_upload

Parameters

NameInTypeRequiredDescription
sourceUrlbody
string (uri)
•
Public http(s) URL the toolkit fetches server-side. Images and video only, up to 512 MB.
filenamebody
string
—
Name to store the file under. Defaults to the last path segment of the URL.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Media asset id. Use it to attach the asset to a post.
key
string
•
Object key in the product bucket. Private — hand it to no one, it is not a URL.
mime
string | null
•
Stored media type, or null while still pending.
error
string | null
•
Why the asset is failed — a readable reason, or null when nothing went wrong.
source
stringone of: url, upload
•
How the bytes arrived: url (fetched by the toolkit) or upload (PUT by the app).
status
stringone of: pending, ready, failed
•
Storage status: pending (the bytes are not in the bucket yet) -> ready (stored, attachable to a post) or failed (ingestion gave up; see error).
viewUrl
string (uri) | null
•
One-hour signed GET URL for a ready asset, or null while pending or failed. Treat it as a bearer link.
filename
string | null
•
Original filename, kept for display only.
createdAt
string
•
ISO-8601 creation time.
sizeBytes
integer | null
•
Stored size in bytes, or null while pending.
sourceUrl
string | null
•
The URL the bytes were fetched from, if any.
updatedAt
string
•
ISO-8601 time of the last change.
viewUrlExpiresAt
string (date-time) | null
•
ISO-8601 expiry of the signed view URL, or null when no view URL is available.
GET/content/media/:id

Read one media asset: its storage status, type and size.

MCP tool: content_media_get

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The media asset id returned when it was created.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Media asset id. Use it to attach the asset to a post.
key
string
•
Object key in the product bucket. Private — hand it to no one, it is not a URL.
mime
string | null
•
Stored media type, or null while still pending.
error
string | null
•
Why the asset is failed — a readable reason, or null when nothing went wrong.
source
stringone of: url, upload
•
How the bytes arrived: url (fetched by the toolkit) or upload (PUT by the app).
status
stringone of: pending, ready, failed
•
Storage status: pending (the bytes are not in the bucket yet) -> ready (stored, attachable to a post) or failed (ingestion gave up; see error).
viewUrl
string (uri) | null
•
One-hour signed GET URL for a ready asset, or null while pending or failed. Treat it as a bearer link.
filename
string | null
•
Original filename, kept for display only.
createdAt
string
•
ISO-8601 creation time.
sizeBytes
integer | null
•
Stored size in bytes, or null while pending.
sourceUrl
string | null
•
The URL the bytes were fetched from, if any.
updatedAt
string
•
ISO-8601 time of the last change.
viewUrlExpiresAt
string (date-time) | null
•
ISO-8601 expiry of the signed view URL, or null when no view URL is available.
POST/content/media/:id/finalize

Confirm a signed-URL upload. The bucket is asked what was actually stored, and the asset becomes ready. Fails while no object has been uploaded yet.

MCP tool: content_media_finalize

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The media asset id returned when it was created.

Response

Returns object.

FieldTypeAlwaysDescription
id
string
•
Media asset id. Use it to attach the asset to a post.
key
string
•
Object key in the product bucket. Private — hand it to no one, it is not a URL.
mime
string | null
•
Stored media type, or null while still pending.
error
string | null
•
Why the asset is failed — a readable reason, or null when nothing went wrong.
source
stringone of: url, upload
•
How the bytes arrived: url (fetched by the toolkit) or upload (PUT by the app).
status
stringone of: pending, ready, failed
•
Storage status: pending (the bytes are not in the bucket yet) -> ready (stored, attachable to a post) or failed (ingestion gave up; see error).
viewUrl
string (uri) | null
•
One-hour signed GET URL for a ready asset, or null while pending or failed. Treat it as a bearer link.
filename
string | null
•
Original filename, kept for display only.
createdAt
string
•
ISO-8601 creation time.
sizeBytes
integer | null
•
Stored size in bytes, or null while pending.
sourceUrl
string | null
•
The URL the bytes were fetched from, if any.
updatedAt
string
•
ISO-8601 time of the last change.
viewUrlExpiresAt
string (date-time) | null
•
ISO-8601 expiry of the signed view URL, or null when no view URL is available.
POST/content/media/upload-url

Get a time-limited signed URL to PUT a file straight into the product bucket. Creates a pending asset; call content_media_finalize once the upload finishes.

MCP tool: content_media_create_upload_url

Parameters

NameInTypeRequiredDescription
contentTypebody
string
•
The media type the app will PUT, e.g. video/mp4. Must be image/* or video/*.
filenamebody
string
—
Name to store the file under, for display purposes.

Response

Returns object.

FieldTypeAlwaysDescription
asset
object
•
The pending asset row. It turns ready on finalize.
expiresAt
string
•
ISO-8601 time after which the upload URL stops working.
uploadUrl
string
•
Time-limited signed PUT URL. Upload the bytes to it, then call the finalize tool.
contentType
string
•
The Content-Type header the PUT must send — the signature covers it.
GET/content/metrics/channels/:id

Daily snapshots of a channel itself — follower count and channel-level reach over time. Sampled once a day while the channel is publishing; a channel with nothing published in the last 30 days stops being sampled, and one whose network reports no analytics is never sampled at all.

MCP tool: content_metrics_channel_series

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The channel id, from content_channels_list.
fromquery
string (date-time)
—
ISO-8601 lower bound on capture time, inclusive. Omit for "from the beginning".
toquery
string (date-time)
—
ISO-8601 upper bound on capture time, inclusive. Omit for "up to now".
limitquery
integer
—
Maximum number of snapshots to return, oldest first.

Response

Returns object.

FieldTypeAlwaysDescription
points
object[]
•
Daily snapshots, oldest first.
network
stringone of: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky, telegram
•
The network the channel publishes to.
analytics
stringone of: full, basic, none
•
What this network reports for this account. "none" means no snapshot will ever be taken — a personal Instagram profile has no API at all; "basic" means fewer numbers than a business account gets, so an absent metric is the network's silence, not a zero.
channelId
string (uuid)
•
The channel these snapshots belong to.
GET/content/metrics/posts/:id

Metric snapshots of one published post on one channel, over time — how reach and engagement grew, not a single current number. Sampled hourly for the first day, then daily, then weekly, then never: a post stops growing and the polling stops with it. Empty until the first snapshot, and always empty where analytics is "none".

MCP tool: content_metrics_post_series

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The publication id, from content_publications_schedule or content_publications_list.
fromquery
string (date-time)
—
ISO-8601 lower bound on capture time, inclusive. Omit for "from the beginning".
toquery
string (date-time)
—
ISO-8601 upper bound on capture time, inclusive. Omit for "up to now".
limitquery
integer
—
Maximum number of snapshots to return, oldest first.

Response

Returns object.

FieldTypeAlwaysDescription
latest
object | null
•
The newest snapshot as flat, named numbers — what to read when you want "how is this post doing" rather than the whole curve. Null when nothing has been captured yet.
points
object[]
•
Snapshots oldest first. Readings over time, not a current value: reach keeps growing for weeks. Empty means nothing has been captured yet.
network
stringone of: linkedin, x, youtube, instagram, reddit, facebook, tiktok, threads, pinterest, bluesky, telegram, unknown
•
The network the channel publishes to. "unknown" means the channel behind this publication can no longer be read — the publication outlives the channel binding.
analytics
stringone of: full, basic, none
•
What this network reports for this account. "none" means no snapshot will ever be taken — a personal Instagram profile has no API at all; "basic" means fewer numbers than a business account gets, so an absent metric is the network's silence, not a zero.
channelId
string (uuid)
•
The channel it was published to.
publicationId
string (uuid)
•
The publication these snapshots belong to.
GET/content/posts

List posts, including ideas, each with its outputs and their states. Filter by status (partially_published for posts with some outputs out and others not) or folderId (null for unfiled posts). With a folder filter, posts appear in plan order; otherwise newest first.

MCP tool: content_posts_list

Parameters

NameInTypeRequiredDescription
statusquery
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
—
Return only posts in this status.
folderIdquery
string (uuid) | null
—
Filter to one folder, or null for posts in no folder. Omit for posts in every folder.
limitquery
integer
—
Maximum number of posts to return (1-100, default 50).
offsetquery
integer
—
How many posts to skip, for paging.

Response

Returns object.

FieldTypeAlwaysDescription
posts
object[]
•
The page of posts, ordered by position when filtered to a folder and newest first otherwise.
total
integer
•
Total number of matching posts, ignoring paging.
POST/content/posts

Create a content plan item. Write the text into each output (targets[].text): networks differ, and the base text is only optional source text for outputs that have none. A title with no text anywhere starts as an idea; text in any output or as base text starts as a draft. Optionally place it in a folder and add private notes, media and outputs (targets): a network and a variant each, several per network allowed, each with optional own media. Use content_posts_to_draft for an idea, then content_posts_submit when every output has publishable text.

MCP tool: content_posts_create

Parameters

NameInTypeRequiredDescription
titlebody
string | null
—
Optional plan title, up to 300 characters. Required when text is empty to create an idea.
notesbody
string | null
—
Private plan notes, up to 20,000 characters. They are not published.
folderIdbody
string (uuid) | null
—
Folder in this product to place the post in, or null for no folder. A new post goes last in that folder.
textbody
string
—
Optional base markdown text: source text an output without its own text publishes. Networks differ, so prefer writing each output its own targets[].text and leave this empty. A title with no text anywhere creates an idea; text here or in any output creates a draft.
mediabody
string[]
—
Media references attached to the post, in display order. Opaque strings — the toolkit does not upload or resolve them.
targetsbody
object[]
—
The outputs of this post: for each, a network, a post type, an optional text override, the network-specific fields and optional own media. Several outputs may share a network. A post needs at least one output before it can be submitted, and it can only be scheduled to channels of networks it has an output for. Replaces the whole list; send each existing output with its id.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
GET/content/posts/:id

Read one post: its current text, status, version numbers and outputs — one entry per output with its state (none, open, uncertain, failed, published, skipped) and the publication that decides it. The way to re-read a post mid-run — after a wait, after an approval, after a publication settled.

MCP tool: content_posts_get

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
PATCH/content/posts/:id

Edit plan title or notes in any status without changing approval or version. Keep each output's own text in targets[].text — networks differ; the base text is optional source text. Editing text, media or targets creates a new immutable version; an approved post returns to pending_approval. A post that is scheduled, partially_published, published or failed cannot be edited — create a new post.

MCP tool: content_posts_update

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id returned by content_posts_create.
titlebody
string | null
—
New plan title, or null to clear it. Changing it does not create a content version or revoke approval.
notesbody
string | null
—
New private plan notes, or null to clear them. Changing them does not create a content version or revoke approval.
textbody
string
—
Replacement text, in markdown; it may be empty for an idea or draft. Omit to keep the current text.
mediabody
string[]
—
Replacement media list (replaces, never merges). Omit to keep the current media.
targetsbody
object[]
—
Replacement output list (replaces, never merges). Omit to keep the current outputs. Send each kept output with its id; an output without an id is new. Resending the stored outputs — in any order, with or without inherited media — is not an edit. Changing one is an edit like changing the text: a new version, and an approved post returns to pending_approval.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:id/approve

Approve a post awaiting approval. The approval binds to the current version — a later edit revokes it.

MCP tool: content_posts_approve

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:id/media/attach

Attach stored media assets to a post, appended in the given order. Only assets that are ready can be attached. This counts as an edit: the post gets a new version and an approved post returns to pending_approval.

MCP tool: content_posts_attach_media

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id.
mediaIdsbody
string (uuid)[]
•
Media asset ids, in the order they should appear on the post.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:id/media/detach

Remove media assets from a post, keeping the order of the rest. Like any edit, it produces a new version and returns an approved post to pending_approval. Removing the only video an output with a cover inherits is refused with 400 cover_without_video: clear that output's cover with content_posts_update first.

MCP tool: content_posts_detach_media

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id.
mediaIdsbody
string (uuid)[]
•
Media asset ids to remove from the post.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:id/submit

Submit a draft for approval. Only a draft can be submitted, and only once it has at least one output and every output has non-empty text and its required variant fields filled.

MCP tool: content_posts_submit

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
GET/content/posts/:id/versions

List every version of a post, oldest first — the audit trail of what was written and by whom.

MCP tool: content_posts_versions

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
postId
string (uuid)
•
The post these versions belong to.
versions
object[]
•
Every version, oldest first.
POST/content/posts/:postId/delete

Delete an idea or draft only if it has no publication history. Cancelled and failed publications also block deletion. This deletes its content versions and emits content/post.deleted; other statuses return post_not_deletable.

MCP tool: content_posts_delete

Parameters

NameInTypeRequiredDescription
postIdpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
postId
string (uuid)
•
The post id returned by content_posts_create.
deleted
booleanone of: true
•
The post and its content versions were deleted.
POST/content/posts/:postId/move

Move a post in any status into a folder, before another post there, or out to the unfiled plan. This changes only plan order, never approval or content version. The destination must belong to this product.

MCP tool: content_posts_move

Parameters

NameInTypeRequiredDescription
postIdpath
string (uuid)
•
The post id returned by content_posts_create.
folderIdbody
string (uuid) | null
•
Destination folder in this product, or null to leave the post unfiled.
beforePostIdbody
string (uuid)
—
Put the post immediately before this post in the destination folder. Omit to append it.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:postId/skip-output

Mark one output of an approved post as "won't publish": it counts as closed, so a post whose other outputs are all published becomes published. It is not a content edit — no new version, the approval stands — and content_posts_unskip_output undoes it. Only past approval (409 post_not_approved otherwise). Refused with 409 output_has_live_publication while the output has a queued or in-flight publication (cancel it first), 409 already_published once it is out, 409 may_already_be_live while a finished publication of it may be live, 409 variant_not_found for an unknown output. Schedule, publish and record of a skipped output answer 409 output_skipped.

MCP tool: content_posts_skip_output

Parameters

NameInTypeRequiredDescription
postIdpath
string (uuid)
•
The post id returned by content_posts_create.
variantIdbody
string
•
The output to act on: a targets[].id (or outputs[].variantId) from content_posts_get.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:postId/to-draft

Move an idea to draft, or take a post awaiting approval back to draft, keeping its title, text and version (no new version; the submission is withdrawn). Only an idea or a pending_approval post can make this transition. Add text or output texts before content_posts_submit.

MCP tool: content_posts_to_draft

Parameters

NameInTypeRequiredDescription
postIdpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:postId/to-idea

Move a draft back to idea without changing its content version. Only a draft can make this transition; use content_posts_to_draft when it is ready for approval.

MCP tool: content_posts_to_idea

Parameters

NameInTypeRequiredDescription
postIdpath
string (uuid)
•
The post id returned by content_posts_create.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
POST/content/posts/:postId/unskip-output

Undo content_posts_skip_output: the output can be scheduled, published or recorded again, and the post status is recomputed. Always allowed past approval; unskipping an output that is not skipped changes nothing.

MCP tool: content_posts_unskip_output

Parameters

NameInTypeRequiredDescription
postIdpath
string (uuid)
•
The post id returned by content_posts_create.
variantIdbody
string
•
The output to act on: a targets[].id (or outputs[].variantId) from content_posts_get.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Post id.
text
string
•
The current text of the post, in markdown.
media
string[]
•
Media references attached to the current version.
notes
string | null
•
Private plan notes, or null when unset.
title
string | null
•
Plan title, or null when unset.
author
string
•
Identity id of whoever composed the post.
status
stringone of: idea, draft, pending_approval, approved, scheduled, partially_published, published, failed
•
Post lifecycle status: idea (may have no text) -> draft (being written) -> pending_approval (submitted) -> approved (cleared to publish). Past approval the status follows EVERY output of the approved version (see outputs): scheduled while an output is queued or in flight and none is out yet; partially_published once some outputs are out and others are still queued, failed or never scheduled; published once every output is out; failed when an output gave up and none is out or queued; back to approved when nothing is live any more (all cancelled). A post in any of these five statuses can still have an output scheduled, including a failed one again.
outputs
object[]
•
One entry per output of this post, in targets order, with the state its publications add up to and the publication that decides it. Before approval every output is `none`. The post's status past approval is derived from exactly these states.
targets
object[]
•
The outputs of this post — a network and a variant each; several may share a network.
folderId
string (uuid) | null
•
Folder containing this post, or null.
position
integer | null
•
Order within its folder, or null for an unfiled post.
createdAt
string (date-time)
•
ISO-8601 creation time.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
currentVersion
integer
•
Version number of the current text.
approvedVersion
integer | null
•
The version an approval binds to, or null. Cleared on every edit: approving one text never covers another.
GET/content/publications

List publications — the queue and the timeline — newest slot first.

MCP tool: content_publications_list

Parameters

NameInTypeRequiredDescription
statequery
stringone of: pending, publishing, published, failed, cancelled
—
Return only publications in this state.
postIdquery
string (uuid)
—
Return only publications of this post.
channelIdquery
string (uuid)
—
Return only publications to this channel.
limitquery
integer
—
Maximum number to return (1-100, default 50).
offsetquery
integer
—
How many to skip, for paging.
scheduledFromquery
string (date-time)
—
Return only publications scheduled at or after this ISO-8601 time.
scheduledToquery
string (date-time)
—
Return only publications scheduled at or before this ISO-8601 time.

Response

Returns object.

FieldTypeAlwaysDescription
total
integer
•
Total number of matching publications, ignoring paging.
publications
object[]
•
The page of publications, newest slot first.
POST/content/publications

Queue one OUTPUT of an approved post for publication to one channel at a given time. A post's outputs are its targets (content_posts_get: targets[].id) — a network and a variant each, several per network allowed, e.g. a YouTube video and two Shorts. What goes out is that output of the post's APPROVED version: its text, post type, fields and media (its own list, or the post's when it inherits); there is no `text` parameter: per-output text lives in `targets[].text`, set with content_posts_update. variantId picks the output; omit it when the channel's network has exactly one output and it is inferred. When the network has several outputs and none is named, the call is refused with 409 variant_required and the list of outputs — pick one and call again. An output of another network is 409 network_not_targeted; an unknown id is 409 variant_not_found. On a reminder channel this does not call the network: at the scheduled time a person is notified to publish by hand, and confirms afterwards with content_publications_confirm. The channel must be on (enabled true in content_channels_list); a channel that is off is refused with 409 channel_disabled — turn it on with content_channels_update or pick another channel. An output goes to a channel once: while it has a publication there that is pending, publishing or published, a second one is refused with 409 already_scheduled naming that publication and output — move it with content_publications_reschedule, or cancel it with content_publications_cancel and schedule again; the post's OTHER outputs may still be scheduled to the same channel. A cancelled or failed publication does not count. Repeating a call with the same idempotency key (by default derived from post, channel, output and time) returns its publication, not a conflict — unless that publication was cancelled or failed: then nothing is queued and the call is refused with 409 idempotency_key_spent; pick a different time or pass a new idempotencyKey.

MCP tool: content_publications_schedule

Parameters

NameInTypeRequiredDescription
postIdbody
string (uuid)
•
The post to publish. It must already be approved — an unapproved version never publishes — and it must have an output for the channel's network.
channelIdbody
string (uuid)
•
The channel to publish to. Its network must be one the post has an output for; what goes out is that output of the post's approved version.
variantIdbody
string
—
Which OUTPUT of the post to publish: a targets[].id from content_posts_get. Omit when the channel's network has exactly one output — it is inferred. When the network has several (a YouTube video and two Shorts), omitting it is refused with 409 variant_required listing them; pick one and call again. An id of another network's output is refused with 409 network_not_targeted; an id the post does not have with 409 variant_not_found.
scheduledAtbody
string (date-time)
•
ISO-8601 time to publish. In the past means "as soon as the next tick runs".
idempotencyKeybody
string
—
Your own key for this publishing intent, unique within the product. Resending the same key returns the SAME publication instead of creating a second one — a duplicate in a client feed is the worst defect this product can ship. Omit it and one is derived from post, channel and time.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
GET/content/publications/:id

Read one publication: its state, its slot, and where it ended up.

MCP tool: content_publications_get

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The publication id returned by content_publications_schedule.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/:id/cancel

Cancel a publication that has not finished. A publication whose reminder already went out can still be cancelled — until someone confirms it. An auto publication that is being sent to the network right now is refused with 409 publication_in_flight: wait for its outcome. A finished publication that may still be live (its output is uncertain) blocks the output until a person settles it: confirm it if the post is on the network, or cancel it with checkedNotLive: true after checking that it is not.

MCP tool: content_publications_cancel

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The publication id returned by content_publications_schedule.
checkedNotLivebody
boolean
—
Only for a FINISHED publication that may still be live (an output in state uncertain: an automatic attempt ended without an answer). Pass true to state that you looked at the network and the post is NOT there; the publication then stops blocking its output. Without it such a cancel is refused with 409 may_already_be_live. Refused with 409 publication_is_live when the network itself reported the post — confirm it instead. Ignored for a publication that is still open.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/:id/confirm

Confirm that a person published the post by hand. Supply externalUrl to record its URL; omit it to store no URL. This closes the publication. Confirmation remains available after publication when the person did not confirm at the time, and for a finished publication that may be live (its output is uncertain) once the person has seen the post on the network. An auto publication that is being sent to the network right now is refused with 409 publication_in_flight.

MCP tool: content_publications_confirm

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The publication id returned by content_publications_schedule.
externalUrlbody
string (uri)
—
URL of the post the person actually published. Worth supplying — it is what identifies the post later.
externalIdbody
string
—
The network's own id for the post, if known.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/:id/remind

Send the publish reminder AGAIN. Repeat reminders are never automatic: the system cannot double-publish, but a person can, so a second nudge only ever happens because someone asked for it. Only for a reminder channel whose first reminder went out: an auto channel is refused with 409 not_a_reminder_channel, and an auto publication being sent right now with 409 publication_in_flight.

MCP tool: content_publications_remind

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The publication id returned by content_publications_schedule.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/:id/reschedule

Move a publication to a new time. It returns to the queue, and the reminder for the old slot is spent — a new one goes out at the new time. An auto publication that is being sent to the network right now is refused with 409 publication_in_flight; one whose channel has been turned off is refused with 409 channel_disabled.

MCP tool: content_publications_reschedule

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The publication id returned by content_publications_schedule.
scheduledAtbody
string (date-time)
•
New ISO-8601 time. The publication returns to the queue.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/publish

Publish NOW: the same queue, scheduled for this instant, publishing one output of the post's approved version to the channel (there is no `text` parameter: per-output text lives in `targets[].text`, set with content_posts_update). variantId picks the output; it is inferred when the channel's network has exactly one, and refused with 409 variant_required (listing the outputs) when it has several and none is named. There is no separate synchronous path — a fast path would differ exactly where it matters, on failure. The same one-publication-per-output-per-channel rule as content_publications_schedule: if that output already has a pending, publishing or published publication on the channel, this is refused with 409 already_scheduled naming it. An idempotencyKey already spent on a cancelled or failed publication is refused with 409 idempotency_key_spent.

MCP tool: content_publications_publish

Parameters

NameInTypeRequiredDescription
postIdbody
string (uuid)
•
The post to publish. It must already be approved and have an output for the channel's network.
channelIdbody
string (uuid)
•
The channel to publish to. What goes out is the chosen output of the post's approved version.
variantIdbody
string
—
Which OUTPUT of the post to publish: a targets[].id from content_posts_get. Omit when the channel's network has exactly one output — it is inferred. When the network has several (a YouTube video and two Shorts), omitting it is refused with 409 variant_required listing them; pick one and call again. An id of another network's output is refused with 409 network_not_targeted; an id the post does not have with 409 variant_not_found.
idempotencyKeybody
string
—
Your own key for this publishing intent, unique within the product. Resending the same key returns the SAME publication instead of creating a second one — a duplicate in a client feed is the worst defect this product can ship. Omit it and one is derived from post, channel and time.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/record

Record that a person already published one OUTPUT of an approved post by hand — no scheduling needed. This never publishes anything: it stores the fact, and the post's status follows (one of two outputs recorded → partially_published; every output published or skipped → published). When the output has a publication on its network that is queued, reminded or may already be live, THAT publication is confirmed (as content_publications_confirm would); otherwise a publication is stored already published, which nothing ever sends or reminds. An output goes to a network once: one already out on any channel of the network is refused with 409 already_published naming it, one being sent by the automatic publisher right now with 409 publication_in_flight (wait for its outcome), a skipped one with 409 output_skipped (content_posts_unskip_output first). Only for a post past approval (409 post_not_approved). A queued automatic publication the publisher has claimed but not started sending is confirmed too, and then never sent. Repeating the same call (same post, output and channel) returns the same publication; a record is stored once, so a repeat naming a different publishedAt or externalUrl is refused with 409 record_mismatch listing the stored values.

MCP tool: content_publications_record

Parameters

NameInTypeRequiredDescription
postIdbody
string (uuid)
•
The approved post one of whose outputs a person published by hand.
variantIdbody
string
—
Which OUTPUT was published: a targets[].id from content_posts_get. Omit when the channel's network has exactly one output (or, without channelId, when the post has exactly one output). Several and none named: 409 variant_required listing them; an id of another network's output with a channelId: 409 network_not_targeted; an id the post does not have: 409 variant_not_found.
channelIdbody
string (uuid)
—
The channel it went out on (content_channels_list). Omit to file it under the output's network's reminder channel; a network with none is refused with 409 no_reminder_channel.
externalUrlbody
string (uri)
—
URL of the post on the network. Worth supplying — it is what identifies the post later.
externalIdbody
string
—
The network's own id for the post, if known.
publishedAtbody
string (date-time)
—
ISO-8601 time the post went out; now when omitted. A time in the future is refused with 400.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
Publication id.
text
string
•
The exact text that will be published to this channel — markdown already flattened to plain network text at schedule time. Not the markdown source; that stays on the post.
media
string[]
•
The media asset ids this publication sends — the output's own list, or the post's when the output inherits — copied when it was scheduled. What the adapter uploads, character for character.
state
stringone of: pending, publishing, published, failed, cancelled
•
pending (queued) -> publishing (the reminder was sent; a person is publishing by hand) -> published (confirmed) | failed | cancelled.
fields
object
•
The network variant fields it goes out with — a YouTube title, a Reddit subreddit — copied from the post's approved output when it was scheduled.
postId
string (uuid)
•
The post being published.
costUsd
number | null
•
What publishing this costs in USD, computed when it was scheduled. On X a post carrying a link costs 13x a plain one. Null means the cost is not known — an auto channel refuses to dispatch it.
warning
string | null
•
Set on a published publication when something did not go as asked but the post is out — e.g. YouTube refused the cover as the thumbnail (an unverified channel, a file too large). The post is NOT retried; fix it on the network by hand. Null otherwise.
attempts
integer
•
How many dispatch attempts have been made.
postType
string | null
•
The post type this publication goes out as (video, short, reel, post, ...), copied from the post's approved variant when it was scheduled. Null on a publication scheduled before post targets existed.
channelId
string (uuid)
•
The channel it is published to.
costBasis
string | nullone of: plain, link, free
•
Which rate produced costUsd: `plain` the flat per-post rate, `link` the higher rate a post carrying a link is charged, `free` a channel whose rates are both zero. Null when the cost is not known.
createdAt
string (date-time)
•
ISO-8601 creation time.
lastError
string | null
•
The most recent failure, if any.
updatedAt
string (date-time)
•
ISO-8601 time of the last change.
variantId
string
•
The post output this publication is bound to (targets[].id). One live publication per post × channel × output. A publication scheduled before outputs existed carries the channel's network name.
externalId
string | null
•
The network's id for the published post, once known.
externalUrl
string | null
•
URL of the published post, once known.
publishedAt
string (date-time) | null
•
ISO-8601 time it was confirmed published.
scheduledAt
string (date-time)
•
ISO-8601 time the publication is due.
coverMediaId
string | null
•
The output's cover image asset id, copied when it was scheduled, or null for none. YouTube sets it as the video's thumbnail after the upload; a reminder links it for the person publishing by hand.
publicationId
string (uuid)
•
The publication id again, under the name the content/publication.settled event uses to report this publication finishing. Always identical to id.
reminderCount
integer
•
How many reminders have been sent for this publication.
idempotencyKey
string
•
The key that makes a retry the same publication.
reminderSentAt
string (date-time) | null
•
ISO-8601 time the most recent reminder went out, or null if none has.
POST/content/publications/validate

Dry run: check one output of a post per channel WITHOUT scheduling anything. Per channel entry, variantId names the output (targets[].id); omit it when the channel's network has one output and it is inferred — with several and none named the entry reports variant_required and the outputs to pick from. Returns everything that would go wrong — a network the post has no output for, a required variant field left empty, a post type that needs a video, text too long, the output's media not stored yet, a link a network will not linkify — and what publishing would cost. On X a post carrying a link costs $0.20 against $0.015 for a plain one, so call this before you schedule.

MCP tool: content_publications_validate

Parameters

NameInTypeRequiredDescription
postIdbody
string (uuid)
•
The post to check. It does not have to be approved yet — this never publishes.
channelsbody
object[]
•
One entry per channel you are considering. Check them all in one call.
scheduledAtbody
string (date-time)
—
The slot you intend to use, ISO-8601. Only the daily ceiling depends on it; omit for "now".

Response

Returns object.

FieldTypeAlwaysDescription
ok
boolean
•
True when nothing blocks scheduling. False when any channel carries an issue of severity "error" — the same fact as the issue list below, stated once so it can be branched on.
postId
string (uuid)
•
The post that was checked.
channels
object[]
•
One result per requested channel, in the order they were given.
errorCount
integer
•
How many error-severity issues there are across every channel. Warnings are not counted: they do not block scheduling.
firstErrorMessage
string | null
•
The first error message in report order, ready to show a person or put in a notification. Null when there are no errors.
Was this page helpful?
Esc

Start typing to search the docs.

↑↓navigate↵select