Agency publishing formats and settings
Agency client posts use the Company API at https://api.publora.com/api/v1/company
and the company_* MCP tools. Discover available formats with
GET /api/v1/company/platforms or company_context action platforms before using
these settings. The returned registry is authoritative
for your environment.
Use company_context to choose an accessible Company and Workspace, then
company_channels to copy each exact channelKey. API requests use
x-publora-key and the selected X-Publora-Workspace-Id; MCP commands take
workspaceId. Permissions follow the caller's current Workspace role.
Personal post tools and personal upload endpoints do not access Agency posts.
Save platform settings
Create a draft with POST /api/v1/company/post-groups; update it with
PATCH /api/v1/company/post-groups/:postGroupId. Send JSON and a stable
Idempotency-Key: choose a unique key for each new intended change and keep it
only for retries of the identical request. The MCP equivalent is company_save_post with
command.action set to create or update and the fields inside command.draft.
platformSettings replaces the complete settings map. Preserve settings for the
other selected platforms when changing one. Only selected platforms may carry
settings; unknown fields and nested properties are rejected. Drafts may be
incomplete; scheduling validates the full saved post and ready uploaded media.
| Platform | Company settings | Rules |
|---|---|---|
videoType: REELS or STORIES, coverUrl, shareToFeed |
A Story requires exactly one image or one video; captions are omitted. Reels accept a public JPEG cover URL and feed sharing. Image albums remain feed posts. | |
| Threads | replyControl: everyone, accounts_you_follow, mentioned_only or empty |
Empty uses the provider default. Reply controls do not enable post chains. |
repostEnabled, repostParentUrn, repostVisibility |
Use a canonical urn:li:share:… or urn:li:ugcPost:…. Commentary is optional and media is forbidden. Visibility is PUBLIC, CONNECTIONS or empty; Pages require PUBLIC. |
|
| TikTok | commercialContent, brandOrganic, brandedContent |
All are booleans. Commercial content requires your brand, a paid partnership, or both. Paid partnerships cannot use SELF_ONLY. Existing creator privacy and interaction options still apply; scheduling requires viewerSetting. |
| YouTube | tags, playlist, thumbnail |
Tags are a string array. Playlist and thumbnail references use the exact objects below. |
YouTube tags are trimmed and limited to 500 characters in total, including commas
and quotation marks around tags containing spaces. A playlist is
{id:"PL…",platformId:"youtube-CHANNEL_ID"}: select exactly one YouTube channel
and use its complete channel key. IDs are at most 200 characters and channel keys
at most 300. Send {id:"",platformId:""} to clear it. Choose a new playlist when
changing the YouTube channel.
A thumbnail is {mediaId:"24_HEX_MEDIA_ID"} belonging to this draft and Workspace.
Send {mediaId:""} to clear it. External URLs and personal media IDs are rejected.
Playlist addition and thumbnail setting run after video processing and are best
effort: a failure of either does not republish a successfully uploaded video.
Example: an Instagram Story draft, followed by the ordinary Company media upload
flow for a single image or video. Set STORY_CREATE_KEY once for this new draft;
when retrying, keep its value and rerun only the curl command:
STORY_CREATE_KEY="$(uuidgen)"
curl -X POST 'https://api.publora.com/api/v1/company/post-groups' \
-H 'x-publora-key: sk_YOUR_API_KEY' \
-H 'X-Publora-Workspace-Id: YOUR_WORKSPACE_ID' \
-H "Idempotency-Key: $STORY_CREATE_KEY" \
-H 'Content-Type: application/json' \
-d '{"platforms":["instagram-YOUR_ACCOUNT_ID"],"platformSettings":{"instagram":{"videoType":"STORIES"}}}'For a Reel, set the cover and feed sharing in the same draft settings map:
{
"platformSettings":{
"instagram":{
"videoType":"REELS",
"coverUrl":"https://cdn.example.com/covers/reel.jpg",
"shareToFeed":false
}
}
}coverUrl is trimmed, limited to 2,048 characters and must be a publicly reachable
HTTP(S) JPEG URL. An empty string clears the custom cover. Extensionless CDN URLs
are accepted; URLs with a known non-JPEG image suffix are rejected. Instagram
fetches the cover when publishing, so keep it accessible until then. The Company
API does not expose the personal cover-upload endpoint; supply your own public
JPEG URL. Omitted shareToFeed means true; set false to publish only as a Reel.
Both options apply only to Reel videos and are ignored for Stories and feed images.
A LinkedIn repost can have empty content and no attachments:
{
"content":"",
"platforms":["linkedin-YOUR_ACCOUNT_ID"],
"platformSettings":{
"linkedin":{
"repostEnabled":true,
"repostParentUrn":"urn:li:share:123456789",
"repostVisibility":"PUBLIC"
}
}
}Supplying a LinkedIn parent without repostEnabled infers repost mode. Explicitly
setting repostEnabled:false with a nonempty parent, or repostEnabled:true
without one, is invalid. For TikTok,
a true disclosure category infers commercialContent:true when that flag is
omitted; an explicit false flag with a true category is invalid.
Upload an Agency YouTube thumbnail
-
Save a draft with its selected YouTube channel and video.
-
Reserve an auxiliary image at
POST /api/v1/company/post-groups/:postGroupId/media/reservations, using the Company headers and a stableIdempotency-Key:{ "fileName":"thumbnail.png", "contentType":"image/png", "sizeBytes":24576, "type":"image", "purpose":"youtube_thumbnail" } -
PUT the exact bytes to the returned
uploadUrl, using alluploadHeadersand no Publora API key. JPEG or PNG is required, at most 2 MiB and at least 640×360 pixels. Your YouTube channel must be eligible for custom thumbnails. -
Complete with
POST /api/v1/company/post-groups/:postGroupId/media/:mediaFileId/completeand{}. Completion uses the same Company headers and no idempotency key. A pending result means retry completion for the same reservation. -
PATCH the draft's settings, preserving any other desired options:
{ "platformSettings":{ "youtube":{ "privacy":"public", "tags":["restaurant","weekly menu"], "playlist":{"id":"PL_example","platformId":"youtube-YOUR_CHANNEL_ID"}, "thumbnail":{"mediaId":"64b000000000000000000501"} } } }
MCP uses company_media action reserve with purpose:"youtube_thumbnail", then
HTTP PUT, company_media action complete, and company_save_post action
update. All arguments belong inside command.
The thumbnail is auxiliary: it is excluded from ordinary video/image attachments.
GET /api/v1/company/post-groups/:postGroupId/media includes the selected
youtubeThumbnail preview when present. Delete an auxiliary asset with
DELETE /api/v1/company/post-groups/:postGroupId/media/:mediaFileId and {};
deleting the selected asset also clears its reference. Ordinary uploads omit
purpose and keep their existing contract. Recovering failed channels into a
new draft clears the source thumbnail reference; upload/select it on the new draft.
Validation, approvals and retries
Publishing-affecting settings and the selected thumbnail are included in client review. Editing the Story placement, Reels cover/feed sharing, reply audience, repost, disclosure, tags, playlist or thumbnail invalidates existing approval. Finish uploads and edits before requesting a new review. Approval does not schedule a post automatically.
| Response | Meaning | Action |
|---|---|---|
400 AGENCY_CORE_CONTENT_INPUT_INVALID |
Unknown field, invalid settings shape, wrong playlist channel or untrusted thumbnail reference | Correct the draft and use a new key for the changed request. |
422 AGENCY_CORE_MEDIA_TYPE_MISMATCH |
Invalid reservation or uploaded thumbnail metadata | Use a JPEG/PNG within the thumbnail requirements; follow the returned media state before retrying. |
422 AGENCY_CORE_MEDIA_SIZE_EXCEEDED |
The file is larger than allowed (2 MiB for a thumbnail) | Reserve a smaller file. |
429 AGENCY_CORE_MEDIA_WORKSPACE_QUOTA_EXCEEDED |
Workspace upload budget or pending-upload limit reached | Respect Retry-After; complete or delete pending uploads. |
403 AGENCY_CORE_ACCESS_DENIED |
Workspace or role access is unavailable | Refresh Company context and select an accessible Workspace. |
409 Company content/media conflict |
Draft or upload state changed, or the retry body differs | Refetch the current state; retry an uncertain operation with the identical body and key. |
After a lost response, retain the same workspace, resource IDs, body and
idempotency key. Never send Company requests through personal tools as a fallback.
Workspace post-event webhooks are described in Agency webhooks.
Twitter replies/quotes, Threads chains and YouTube categoryId remain outside this extension.
See Agency first comments and the Agency MCP tools.