Changelog
Stay up to date with the latest API changes and improvements
Track all updates to the Zernio API. We announce significant changes here and on our Telegram channel and X (Twitter).
Breaking Change
GET
Single-post lookups can return
Key changes:
• Date defaults/limits:
• Sorting:
• Single post response adds
• Per-platform analytics now include
• List responses add
/v1/analytics now supports richer analytics sync states and more sorting options.Single-post lookups can return
202 when analytics sync is still pending, or 424 when analytics are unavailable because the post failed on all platforms.Key changes:
• Date defaults/limits:
fromDate defaults to 90 days ago, toDate defaults to today, max range 366 days• Sorting:
sortBy now supports date, engagement, impressions, reach, likes, comments, shares, saves, clicks, views• Single post response adds
latePostId, syncStatus (synced/pending/partial/unavailable) and message; status can be published/failed/partial• Per-platform analytics now include
syncStatus (synced/pending/unavailable), platformPostUrl, and errorMessage; analytics may be null• List responses add
posts[].latePostId, posts[].profileId, and overview.dataStalenessNew Feature
Late API now supports X/Twitter engagement actions: retweet, bookmark, and follow (plus undo/remove/unfollow).
Use:
• Retweet:
• Undo retweet:
• Bookmark:
• Remove bookmark:
• Follow:
• Unfollow:
Inbox comment moderation also adds X/Twitter support:
•
•
For X/Twitter, the reply must be in a conversation started by the authenticated user and requires
Use:
• Retweet:
POST /v1/twitter/retweet with accountId, tweetId• Undo retweet:
DELETE /v1/twitter/retweet with accountId, tweetId• Bookmark:
POST /v1/twitter/bookmark with accountId, tweetId• Remove bookmark:
DELETE /v1/twitter/bookmark with accountId, tweetId• Follow:
POST /v1/twitter/follow with accountId, targetUserId (response may include pending_follow for protected accounts)• Unfollow:
DELETE /v1/twitter/follow with accountId, targetUserIdInbox comment moderation also adds X/Twitter support:
•
POST /v1/inbox/comments/{postId}/{commentId}/hide•
DELETE /v1/inbox/comments/{postId}/{commentId}/hideFor X/Twitter, the reply must be in a conversation started by the authenticated user and requires
tweet.moderate.write + X API Basic tier (or higher). Bookmark/follow also require bookmark.write / follows.write scopes, and X API Basic tier (or higher).Improvement
GET /v1/analytics now returns richer media metadata for analytics results.You can render previews and handle carousels consistently using the new fields on both single-post and list responses.
New fields:
•
thumbnailUrl•
mediaType = image | video | gif | document | carousel | text (single-post also supports image | video | carousel | text)•
mediaItems (array of { type: image|video, url, thumbnail }; carousel posts include one entry per slide)Improvement
The
Use
GET /v1/usage-stats response now includes billingAnchorDay.Use
billingAnchorDay (1–31) to determine the day of the month when the billing cycle resets, which can help align usage tracking and reset expectations.Improvement
GBP endpoints now support overriding the target location via optional
This lets you fetch/update reviews, media, attributes, place actions, food menus, and location details for a specific GBP location without changing the account’s selected location.
Use
•
•
•
•
•
•
locationId.This lets you fetch/update reviews, media, attributes, place actions, food menus, and location details for a specific GBP location without changing the account’s selected location.
Use
locationId (query) on:•
GET /v1/accounts/{accountId}/gmb-reviews•
GET/PUT /v1/accounts/{accountId}/gmb-food-menus•
GET/PUT /v1/accounts/{accountId}/gmb-location-details•
GET/POST/DELETE /v1/accounts/{accountId}/gmb-media•
GET/PUT /v1/accounts/{accountId}/gmb-attributes•
GET/POST/DELETE /v1/accounts/{accountId}/gmb-place-actionsNew Feature
Twitter posts now support replying to an existing tweet via
Set
replyToTweetId in TwitterPlatformData.Set
replyToTweetId to publish the first tweet (or the root of a thread) as a reply; subsequent thread items chain normally.replySettings also adds verified (now: following, mentionedUsers, subscribers, verified). Note: replySettings cannot be combined with replyToTweetId.New Feature
New endpoint
Currently supported only for LinkedIn organization/company page accounts (personal profile reaction data is restricted by LinkedIn).
Required params:
Optional:
Response includes
GET /v1/accounts/{accountId}/linkedin-post-reactions returns who reacted to a LinkedIn post, including reactor profile details.Currently supported only for LinkedIn organization/company page accounts (personal profile reaction data is restricted by LinkedIn).
Required params:
accountId (path, LinkedIn org account), urn (query, LinkedIn post URN)Optional:
limit (1–100, default 25), cursorResponse includes
reactions[] with reactionType (LIKE, PRAISE, EMPATHY, INTEREST, APPRECIATION, ENTERTAINMENT), reactedAt, and from (e.g., name, headline, profileUrl, profilePicture), plus pagination.Improvement
GET /v1/connect/{platform} redirect behavior now includes accountId in standard mode.After a successful connect, Zernio’s standard redirect to
redirect_url now appends ?connected={platform}&profileId=X&accountId=Y&username=Z (previously no accountId).In headless mode (
headless=true), the redirect includes raw OAuth data only when a post-OAuth selection step is required (e.g. LinkedIn orgs, Facebook pages). If no selection is needed, the account is created directly and the redirect includes accountId.New Feature
Posts can now be recycled (auto-reposted on a schedule) via
After the original post is published, Zernio will create new scheduled copies at a weekly/monthly interval until an expiration condition is met.
Configure with
•
•
•
•
•
•
Webhooks: a new event
Also:
recycling on POST /v1/posts and PUT /v1/posts/{postId}.After the original post is published, Zernio will create new scheduled copies at a weekly/monthly interval until an expiration condition is met.
Configure with
recycling:•
gap (int)•
gapFreq: week | month•
startDate (date-time, optional)•
expireCount (int, optional)•
expireDate (date-time, optional)•
contentVariations (string[], optional)Webhooks: a new event
post.recycled is available in POST/PUT /v1/webhooks/settings and filterable in GET /v1/webhooks/logs.Also:
GET /v1/tools/youtube/transcript may now return 503, and DELETE /v1/inbox/comments/{postId} may now return 400 when the platform rejects the delete.New Feature
New endpoint
Query params:
•
•
•
Response includes
GET /v1/analytics/post-timeline returns a daily analytics timeline for a specific post (per platform for multi-platform Zernio posts), showing how metrics evolve day-by-day since publishing. Requires the Analytics add-on.Query params:
•
postId (required) — accepts ExternalPost ID, platformPostId, or Zernio Post ID•
fromDate (optional, ISO 8601; default 90 days ago)•
toDate (optional, ISO 8601; default now)Response includes
timeline[] rows with date, platform, platformPostId, and metrics like impressions, reach, likes, comments, shares, saves, clicks, views.New Feature
New validation endpoints are available under
Validate weighted character counts per platform with
Dry-run the full post validation pipeline (same body as
Validate a public media URL and compare against per-platform size limits with
Check subreddit existence/info with
/v1/tools/validate to preflight-check content before publishing.Validate weighted character counts per platform with
POST /v1/tools/validate/post-length (body: { text }) and get per-platform { count, limit, valid }.Dry-run the full post validation pipeline (same body as
POST /v1/posts) with POST /v1/tools/validate/post. Target platforms via platforms[].platform: twitter, instagram, tiktok, youtube, facebook, linkedin, bluesky, threads, reddit, pinterest, telegram, snapchat, googlebusiness. Returns valid plus errors[] and/or warnings[].Validate a public media URL and compare against per-platform size limits with
POST /v1/tools/validate/media (body: { url }). Returns contentType, size, type (image/video/unknown), and platformLimits when available.Check subreddit existence/info with
GET /v1/tools/validate/subreddit using query name.New Feature
New Analytics endpoints are available for aggregated reporting and scheduling optimization (requires the Analytics add-on).
Daily aggregated metrics:
• Filters:
• Returns:
Best times to post:
• Filters:
• Returns:
Content performance decay:
• Filters:
• Returns:
Posting frequency vs engagement:
• Filters:
• Returns:
Daily aggregated metrics:
GET /v1/analytics/daily-metrics• Filters:
platform, profileId, fromDate, toDate• Returns:
dailyData + platformBreakdown with summed metrics (impressions, reach, likes, comments, shares, saves, clicks, views)Best times to post:
GET /v1/analytics/best-time• Filters:
platform, profileId• Returns:
slots grouped by dayofweek (0=Monday..6=Sunday) and hour (UTC 0-23) with avg_engagementContent performance decay:
GET /v1/analytics/content-decay• Filters:
platform, profileId• Returns:
buckets with bucketlabel and avgpctoffinalPosting frequency vs engagement:
GET /v1/analytics/posting-frequency• Filters:
platform, profileId• Returns:
frequency rows with postsperweek, avgengagementrate, weeks_countImprovement
LinkedIn document (PDF/carousel) posts now let you control the displayed document title via
LinkedIn requires a title for document posts; if omitted, Zernio will fall back to the media item title, then the filename.
Use:
•
•
platformSpecificData.linkedin.documentTitle.LinkedIn requires a title for document posts; if omitted, Zernio will fall back to the media item title, then the filename.
Use:
•
platformSpecificData.linkedin.documentTitle•
media[].title (used as the LinkedIn document title if documentTitle is not set; otherwise falls back to filename)New Feature
API keys can now be created with restricted access using
This lets you issue keys limited to specific profiles and/or make keys read-only for safer analytics/integration use.
New request fields:
•
•
•
Key responses now include
scope, profileIds, and permission on POST /v1/api-keys.This lets you issue keys limited to specific profiles and/or make keys read-only for safer analytics/integration use.
New request fields:
•
scope: full | profiles (default full)•
profileIds: required when scope=profiles•
permission: read-write | read (default read-write)Key responses now include
scope, profileIds (populated profile objects when scoped), and permission (e.g., in GET /v1/api-keys and create responses).New Feature
Facebook publishing now supports Reels via
Set
New field for reels:
•
Note:
FacebookPlatformData.contentType.Set
contentType to story or reel (omit for a feed post). Reels require a single vertical video (9:16, 3–60s).New field for reels:
•
title — Reel title (only when contentType=reel)Note:
firstComment applies to feed posts only (not stories or reels).New Feature
New endpoint:
You can now delete a previously published post from a specific social platform while keeping the Zernio post record (platform status becomes
Request body:
Notes: Instagram/TikTok/Snapchat deletion isn’t supported. Telegram deletions may fail for messages older than 48h. YouTube deletion permanently removes the video.
POST /v1/posts/{postId}/unpublish.You can now delete a previously published post from a specific social platform while keeping the Zernio post record (platform status becomes
cancelled).Request body:
platform = threads | facebook | twitter | linkedin | youtube | pinterest | reddit | bluesky | googlebusiness | telegram.Notes: Instagram/TikTok/Snapchat deletion isn’t supported. Telegram deletions may fail for messages older than 48h. YouTube deletion permanently removes the video.
Improvement
Instagram photo tagging now supports tagging specific slides in carousel posts via
This lets you place tags on any image within a carousel. Tags without
Use:
•
Notes:
• Not supported for stories or videos; tags targeting video items (or out-of-range indices) are ignored.
mediaIndex in platformSpecificData.userTags.This lets you place tags on any image within a carousel. Tags without
mediaIndex still default to the first image (index 0).Use:
•
userTags[].mediaIndex (integer, 0-based)Notes:
• Not supported for stories or videos; tags targeting video items (or out-of-range indices) are ignored.
New Feature
POST
You can send a private reply to a Facebook post comment, which opens a Messenger conversation with the commenter (text-only; still limited to 1 private reply per comment within 7 days).
Use
/v1/inbox/comments/{postId}/{commentId}/private-reply now supports Facebook in addition to Instagram.You can send a private reply to a Facebook post comment, which opens a Messenger conversation with the commenter (text-only; still limited to 1 private reply per comment within 7 days).
Use
accountId (Instagram or Facebook) and message in the JSON body. The response platform is now instagram or facebook.Improvement
Google Business Profile posts now support explicitly setting the content language via
If omitted, the language is auto-detected from the post text; set it when auto-detection may be unreliable (short posts, mixed languages, transliteration).
New field:
languageCode in GoogleBusinessPlatformData.If omitted, the language is auto-detected from the post text; set it when auto-detection may be unreliable (short posts, mixed languages, transliteration).
New field:
languageCode (BCP 47, e.g. en, de, es, fr).New Feature
Reddit posting now supports post flairs via
Some subreddits require a flair; you can now fetch available flairs and set the one you want on the post.
New endpoint:
Required query:
New field:
If omitted, the API will attempt to use the first available flair as a fallback.
flairId in platformSpecificData.Some subreddits require a flair; you can now fetch available flairs and set the one you want on the post.
New endpoint:
GET /v1/accounts/{accountId}/reddit-flairsRequired query:
subreddit (without r/)New field:
platformSpecificData.reddit.flairId (string)If omitted, the API will attempt to use the first available flair as a fallback.
Improvement
Instagram conversations now include optional participant profile context via
This lets you show follower/verification info (and follower count) alongside DMs, and use it in routing/automation.
Added to:
•
•
Fields:
•
Webhook update:
•
instagramProfile.This lets you show follower/verification info (and follower count) alongside DMs, and use it in routing/automation.
Added to:
•
GET /v1/inbox/conversations → data[].instagramProfile•
GET /v1/inbox/conversations/{conversationId} → data.instagramProfileFields:
•
isFollower, isFollowing, followerCount, isVerified, fetchedAtWebhook update:
•
WebhookPayloadMessage.message.sender.instagramProfile (Instagram only) with isFollower, isFollowing, followerCount, isVerified.New Feature
Interactive messaging support for the Inbox API.
• Quick replies (
• Buttons (
• Carousels (
• Telegram keyboards (
• Message tags (
• Reply to (
Incoming messages now include
Also added:
POST /v1/inbox/conversations/{conversationId}/messages now supports:• Quick replies (
quickReplies) - Up to 13 quick reply buttons (Instagram, Facebook, Telegram)• Buttons (
buttons) - Up to 3 action buttons: URL, postback, or phone (Instagram, Facebook, Telegram)• Carousels (
template) - Generic template with up to 10 elements (Instagram, Facebook)• Telegram keyboards (
replyMarkup) - Native inline or reply keyboards• Message tags (
messageTag) - Send outside the 24h window: HUMANAGENT (Instagram), CONFIRMEDEVENTUPDATE, POSTPURCHASEUPDATE, ACCOUNTUPDATE, HUMAN_AGENT (Facebook)• Reply to (
replyTo) - Reply to a specific message (Telegram)Incoming messages now include
metadata with quickReplyPayload, postbackPayload, postbackTitle, and callbackData to identify interactive message taps.Also added:
PATCH /v1/inbox/conversations/{conversationId}/messages/{messageId} to edit sent Telegram messages (text and inline keyboard).New Feature
New Account Settings endpoints for managing platform-specific messaging features.
Facebook Persistent Menu (
GET/PUT/DELETE to manage the persistent menu shown in Facebook Messenger conversations. Max 3 top-level items, max 5 nested items.
Instagram Ice Breakers (
GET/PUT/DELETE to manage ice breaker prompts shown when users start a new Instagram DM. Max 4 ice breakers, question max 80 chars.
Telegram Bot Commands (
GET/PUT/DELETE to manage the bot command menu shown in Telegram chats.
Facebook Persistent Menu (
/v1/accounts/{accountId}/messenger-menu)GET/PUT/DELETE to manage the persistent menu shown in Facebook Messenger conversations. Max 3 top-level items, max 5 nested items.
Instagram Ice Breakers (
/v1/accounts/{accountId}/instagram-ice-breakers)GET/PUT/DELETE to manage ice breaker prompts shown when users start a new Instagram DM. Max 4 ice breakers, question max 80 chars.
Telegram Bot Commands (
/v1/accounts/{accountId}/telegram-commands)GET/PUT/DELETE to manage the bot command menu shown in Telegram chats.
Minor
Added 2 new endpoints:
GET /v1/posts/logs - Get publishing logsGET /v1/connections/logs - Get connection logsNew Feature
New Google Business Profile endpoints are now available for managing your GMB listings programmatically.
Location Details (
GET/PUT to read and update business hours, special hours, description, phone numbers, and website. Use
Media (
GET/POST/DELETE to manage photos. Upload via public URL with categories:
Attributes (
GET/PUT to manage amenities and services like
Place Actions (
GET/POST/DELETE to manage booking and ordering buttons. Types include:
Location Details (
/v1/accounts/{accountId}/gmb-location-details)GET/PUT to read and update business hours, special hours, description, phone numbers, and website. Use
readMask and updateMask to specify fields.Media (
/v1/accounts/{accountId}/gmb-media)GET/POST/DELETE to manage photos. Upload via public URL with categories:
COVER, PROFILE, LOGO, EXTERIOR, INTERIOR, FOODANDDRINK, MENU, PRODUCT, TEAMS, ADDITIONALAttributes (
/v1/accounts/{accountId}/gmb-attributes)GET/PUT to manage amenities and services like
hasdelivery, hastakeout, hasoutdoorseating, has_wifi, payment types, etc.Place Actions (
/v1/accounts/{accountId}/gmb-place-actions)GET/POST/DELETE to manage booking and ordering buttons. Types include:
APPOINTMENT, DININGRESERVATION, FOODORDERING, FOODDELIVERY, FOODTAKEOUT, SHOP_ONLINENew Feature
New endpoints for Google Business Profile food menus:
Fetch the full menu structure for a connected GBP location.
Update food menus with sections, items, pricing, dietary info, and allergens.
Menu items support:
•
•
•
•
Only available for GBP locations with food menu support (restaurants, cafes, etc.).
Also:
GET /v1/accounts/{accountId}/gmb-food-menusFetch the full menu structure for a connected GBP location.
PUT /v1/accounts/{accountId}/gmb-food-menusUpdate food menus with sections, items, pricing, dietary info, and allergens.
Menu items support:
•
price with currency code•
dietaryRestriction - VEGETARIAN, VEGAN, GLUTEN_FREE, etc.•
allergen - DAIRY, GLUTEN, SHELLFISH, etc.•
spiciness, servesNumPeople, preparationMethodsOnly available for GBP locations with food menu support (restaurants, cafes, etc.).
Also:
PostAnalytics now includes saves for tracking bookmarks on Instagram and Pinterest.New Feature
The Inbox API now supports Twitter/X for conversations, comments, and comment interactions.
Conversations (
Filter by
Comments (
Twitter/X posts with replies are now included. Also added Threads support for comments listing.
Like/Unlike comments:
Conversations (
GET /v1/inbox/conversations):Filter by
platform=twitter to fetch Twitter/X DMs.Comments (
GET /v1/inbox/comments):Twitter/X posts with replies are now included. Also added Threads support for comments listing.
Like/Unlike comments:
POST and DELETE /v1/inbox/comments/{postId}/{commentId}/like now work with Twitter/X replies.New Feature
The
Values:
•
•
•
This makes it easier to separate analytics for posts you scheduled through Zernio from posts that were published directly on the platform.
GET /v1/analytics endpoint now supports a source query parameter to filter posts by origin.Values:
•
late - only posts scheduled/published via Zernio API•
external - only posts synced from the platform (not posted via Late)•
all - all posts (default)This makes it easier to separate analytics for posts you scheduled through Zernio from posts that were published directly on the platform.
New Feature
The
Three new fields are available:
•
•
•
•
•
•
•
•
•
•
•
These fields are populated when a platform's
PlatformTarget schema now includes detailed error information when posts fail to publish.Three new fields are available:
errorMessage - Human-readable explanation of why the publish failederrorCategory - Programmatic category for handling:•
auth_expired - token expired, reconnect needed•
user_content - content doesn't meet platform requirements•
user_abuse - rate limits or spam detection•
account_issue - account configuration problems•
platform_rejected - policy violation•
platform_error - platform-side issues•
system_error - Zernio infrastructure issues•
unknown - unclassifiederrorSource - Who caused the error:•
user - user action required•
platform - platform-side issue•
system - Zernio system issueThese fields are populated when a platform's
status is failed. Posts with mixed results now return status: "partial" at the post level.New Feature
YouTube uploads now support video categories via the new
You can now specify which category your video belongs to. Defaults to
Common category IDs:
•
•
•
•
•
•
categoryId field in platformSpecificData.You can now specify which category your video belongs to. Defaults to
22 (People & Blogs) if not set.Common category IDs:
•
1 - Film & Animation•
10 - Music•
20 - Gaming•
24 - Entertainment•
27 - Education•
28 - Science & TechnologyNew Feature
Multi-page/multi-location posting is now supported for Facebook, LinkedIn, and Google Business.
You can now post to multiple pages, organizations, or locations from a single account connection by using the same
• Facebook:
• LinkedIn:
• Google Business:
List available targets via:
•
•
•
Also:
You can now post to multiple pages, organizations, or locations from a single account connection by using the same
accountId multiple times with different targets in platformSpecificData:• Facebook:
pageId - post to multiple Pages• LinkedIn:
organizationUrn - post to multiple organizations• Google Business:
locationId - post to multiple locationsList available targets via:
•
GET /v1/accounts/{id}/facebook-page•
GET /v1/accounts/{id}/linkedin-organizations•
GET /v1/accounts/{id}/gmb-locationsAlso:
content is now optional when media is attached or all platforms have customContent set.New Feature
New endpoint:
Send a private DM to the author of a comment on your Instagram post. Useful for handling customer inquiries or sensitive matters privately.
Required body:
•
•
Limitations:
• Instagram only (not available on other platforms)
• One private reply per comment
• Must be sent within 7 days of the comment
• Only works for comments on posts you own
• Requires the Inbox addon
POST /v1/inbox/comments/{postId}/{commentId}/private-replySend a private DM to the author of a comment on your Instagram post. Useful for handling customer inquiries or sensitive matters privately.
Required body:
•
accountId - Instagram social account ID•
message - text to send as DMLimitations:
• Instagram only (not available on other platforms)
• One private reply per comment
• Must be sent within 7 days of the comment
• Only works for comments on posts you own
• Requires the Inbox addon
New Feature
New endpoints for managing Facebook Pages and Google Business Profile locations.
List all Facebook pages the connected account can access, see which one is currently selected.
List all Google Business Profile locations available to the account.
Change the selected GBP location by passing
Useful if you manage multiple pages/locations and need to switch between them programmatically.
GET /v1/accounts/{accountId}/facebook-pageList all Facebook pages the connected account can access, see which one is currently selected.
GET /v1/accounts/{accountId}/gmb-locationsList all Google Business Profile locations available to the account.
PUT /v1/accounts/{accountId}/gmb-locationsChange the selected GBP location by passing
selectedLocationId in the request body.Useful if you manage multiple pages/locations and need to switch between them programmatically.
Improvement
POST /v1/posts now returns
If you post identical content to the same account within 24 hours, you'll get:
Additionally,
• Velocity limit: 15 posts/hour per account
• Account cooldown: Escalating delays (10min → 24h) after repeated errors
• Daily post limits: Platform-specific (X: 20, Pinterest: 25, Instagram/Facebook: 100, Threads: 250, others: 50)
New headers on 429:
These changes also apply to
409 Conflict when duplicate content is detected.If you post identical content to the same account within 24 hours, you'll get:
{
"error": "This exact content was already posted...",
"details": {
"accountId": "...",
"platform": "...",
"existingPostId": "..."
}
}Additionally,
429 responses now include detailed context about which limit was hit:• Velocity limit: 15 posts/hour per account
• Account cooldown: Escalating delays (10min → 24h) after repeated errors
• Daily post limits: Platform-specific (X: 20, Pinterest: 25, Instagram/Facebook: 100, Threads: 250, others: 50)
New headers on 429:
Retry-After, X-RateLimit-Limit, X-RateLimit-RemainingThese changes also apply to
POST /v1/posts/bulk-upload and POST /v1/posts/{postId}/retry.New Feature
YouTube uploads now support
This COPPA compliance field declares whether your video is child-directed content. Defaults to
Set to
Important: YouTube requires this to be explicitly set. If omitted, the video defaults to not made for kids, but may be blocked from views until configured in YouTube Studio.
madeForKids in platformSpecificData.youtube.This COPPA compliance field declares whether your video is child-directed content. Defaults to
false.Set to
true if your video is made for kids. Note: kid-directed videos have restricted features (no comments, no notifications, limited ad targeting).Important: YouTube requires this to be explicitly set. If omitted, the video defaults to not made for kids, but may be blocked from views until configured in YouTube Studio.
Improvement
Analytics responses now include
When an external post originated from a Late-scheduled post, the response now includes the original Zernio Post ID directly. This makes it easier to correlate analytics data with posts created via
The field appears in both single post queries and paginated list responses. It's
latePostId field.When an external post originated from a Late-scheduled post, the response now includes the original Zernio Post ID directly. This makes it easier to correlate analytics data with posts created via
POST /v1/posts.The field appears in both single post queries and paginated list responses. It's
null for posts that weren't scheduled through Zernio.Breaking Change
LinkedIn headless OAuth flow updated
LinkedIn headless mode now uses a token-based approach to retrieve OAuth data, preventing URITOOLONG errors for users with many organizations.
What changed:
After OAuth redirect, you now receive
Call the new endpoint to fetch the data:
Returns:
Important:
• One-time use: data is deleted after fetching
• Data expires after 10 minutes if not fetched
• No authentication required, just the token
Other platforms (Facebook, Pinterest, Google Business, Snapchat) are unchanged.
LinkedIn headless mode now uses a token-based approach to retrieve OAuth data, preventing URITOOLONG errors for users with many organizations.
What changed:
After OAuth redirect, you now receive
pendingDataToken instead of tempToken, userProfile, and organizations in the URL.Call the new endpoint to fetch the data:
GET /v1/connect/pending-data?token=PENDINGDATATOKENReturns:
tempToken, refreshToken, expiresIn, userProfile, organizations, selectionTypeImportant:
• One-time use: data is deleted after fetching
• Data expires after 10 minutes if not fetched
• No authentication required, just the token
Other platforms (Facebook, Pinterest, Google Business, Snapchat) are unchanged.
New Feature
Instagram Reels now support thumbnail offset selection via
Specify a millisecond offset from the start of the video to use as the Reel cover image. Defaults to 0 (first frame).
If you provide a custom thumbnail URL via
thumbOffset in platformSpecificData.Specify a millisecond offset from the start of the video to use as the Reel cover image. Defaults to 0 (first frame).
thumbOffset: integer, minimum 0 (milliseconds)If you provide a custom thumbnail URL via
instagramThumbnail in mediaItems, it takes priority and this offset is ignored.New Feature
New webhook event:
You can now subscribe to notifications when a social account is connected to a profile. The webhook payload includes
Add it to your
account.connectedYou can now subscribe to notifications when a social account is connected to a profile. The webhook payload includes
accountId, profileId, platform, username, and displayName.Add it to your
events array when creating or updating webhooks.New Feature
YouTube daily views breakdown is now available via
GET /v1/analytics/youtube/daily-views. This endpoint returns historical daily view counts for a specific YouTube video, including views, watch time, and subscriber changes. Required parameters include videoId and accountId, with optional date range parameters startDate and endDate.Improvement
Zernio now automatically compresses media that exceeds platform limits during publishing, simplifying the upload process.
Image compression thresholds are set for platforms like
Video compression thresholds include
Image compression thresholds are set for platforms like
Twitter/X: >5 MB, Instagram: >8 MB, Facebook: >10 MB, and more. Video compression thresholds include
Twitter/X: >512 MB, Instagram Stories: >100 MB, Facebook: >4 GB, among others.Breaking Change
The endpoint
POST /v1/profiles/{profileId}/clone-connection has been removed. This endpoint was used to clone an existing connection to a profile, allowing users to manage multiple brands with the same underlying social media account.Improvement
YouTube now supports AI-generated content disclosure via
Set
containsSyntheticMedia in YouTubePlatformData.Set
containsSyntheticMedia to true if your video contains AI-generated or synthetic content that could be mistaken for real people, places, or events. YouTube may add a label to videos when this is set.Improvement
Instagram now supports custom audio names for Reels via
You can set a custom name for the original audio, replacing the default "Original Audio" label. This can only be set once during creation or later from the Instagram audio page in the app.
audioName in platformSpecificData.You can set a custom name for the original audio, replacing the default "Original Audio" label. This can only be set once during creation or later from the Instagram audio page in the app.
Improvement
InstagramPlatformData Schema Update
The
Here are the details of the new
-
-
- Possible values:
- This field determines how a trial reel transitions to a regular reel:
-
-
The rest of the schema remains unchanged, including the parameters
This update enhances your ability to manage Reels effectively, allowing for strategic sharing and performance-based visibility adjustments. Keep this in mind as you plan your content strategy.
The
InstagramPlatformData schema has been updated to include a new parameter: trialParams. This parameter allows for configuration of trial Reels, which are initially shared only with non-followers. Here are the details of the new
trialParams field:-
trialParams: object (optional)-
graduationStrategy: string (required)- Possible values:
MANUAL, SS_PERFORMANCE- This field determines how a trial reel transitions to a regular reel:
-
MANUAL: Requires manual graduation via the Instagram app.-
SS_PERFORMANCE: Automatically graduates based on performance metrics with non-followers.The rest of the schema remains unchanged, including the parameters
contentType, shareToFeed, collaborators, firstComment, and userTags. This update enhances your ability to manage Reels effectively, allowing for strategic sharing and performance-based visibility adjustments. Keep this in mind as you plan your content strategy.
New Feature
New Endpoints Available:
1.
- This endpoint allows you to retrieve publishing logs for all posts. You can filter logs by status (
-
-
-
-
-
-
- The response includes an array of logs and pagination details.
2.
- Use this endpoint to retrieve detailed information about a specific log entry, including full request and response bodies for debugging purposes.
-
- The response contains the log entry details, including the full context of the publishing attempt.
3.
- This endpoint retrieves all publishing logs for a specific post, showing the complete history of publishing attempts across all platforms.
-
-
- The response includes an array of logs specific to the post and the count of logs returned.
1.
GET /v1/logs- This endpoint allows you to retrieve publishing logs for all posts. You can filter logs by status (
status), platform (platform), and action (action). The logs include detailed information about each publishing attempt, such as API requests, responses, and timing data. -
status (string, optional): Filter by log status (options: success, failed, pending, skipped, all).-
platform (string, optional): Filter by platform (options include tiktok, instagram, facebook, etc.).-
action (string, optional): Filter by action type (options: publish, retry, media_upload, etc.).-
days (integer, optional): Number of days to look back (max 7, default 7).-
limit (integer, optional): Maximum number of logs to return (max 100, default 50).-
skip (integer, optional): Number of logs to skip for pagination (default 0).- The response includes an array of logs and pagination details.
2.
GET /v1/logs/{logId}- Use this endpoint to retrieve detailed information about a specific log entry, including full request and response bodies for debugging purposes.
-
logId (string, required): The ID of the log entry you want to retrieve.- The response contains the log entry details, including the full context of the publishing attempt.
3.
GET /v1/posts/{postId}/logs- This endpoint retrieves all publishing logs for a specific post, showing the complete history of publishing attempts across all platforms.
-
postId (string, required): The ID of the post for which you want to retrieve logs.-
limit (integer, optional): Maximum number of logs to return (max 100, default 50).- The response includes an array of logs specific to the post and the count of logs returned.
New Feature
New Endpoints for Pinterest Integration
We have added two new endpoints to enhance your integration with Pinterest in headless mode:
1.
- Summary: List Pinterest Boards after OAuth (Headless Mode)
- Description: This endpoint retrieves a list of Pinterest boards available for selection after initiating OAuth via
- Parameters:
-
-
-
- Responses:
-
-
-
-
-
2.
- Summary: Select a Pinterest Board to complete the connection (Headless Mode)
- Description: Use this endpoint to save the selected board and complete the Pinterest account connection after OAuth.
- Request Body: Must include the following fields:
-
-
-
-
-
-
-
-
- Responses:
-
-
-
-
-
We have added two new endpoints to enhance your integration with Pinterest in headless mode:
1.
GET /v1/connect/pinterest/select-board- Summary: List Pinterest Boards after OAuth (Headless Mode)
- Description: This endpoint retrieves a list of Pinterest boards available for selection after initiating OAuth via
/v1/connect/pinterest with headless=true. It allows you to build your own fully-branded board selector instead of using Zernio's hosted UI.- Parameters:
-
X-Connect-Token (header, required): Short-lived connect token from the OAuth redirect.-
profileId (query, required): Your Zernio profile ID.-
tempToken (query, required): Temporary Pinterest access token from the OAuth callback redirect.- Responses:
-
200: Returns a list of Pinterest boards available for connection, including each board's ID, name, description, and privacy setting.-
400: Missing required parameters.-
401: Unauthorized access.-
403: No access to profile.-
500: Failed to fetch boards.2.
POST /v1/connect/pinterest/select-board- Summary: Select a Pinterest Board to complete the connection (Headless Mode)
- Description: Use this endpoint to save the selected board and complete the Pinterest account connection after OAuth.
- Request Body: Must include the following fields:
-
profileId (string, required): Your Zernio profile ID.-
boardId (string, required): The Pinterest Board ID selected by the user.-
boardName (string, optional): The board name for display purposes.-
tempToken (string, required): Temporary Pinterest access token from OAuth.-
userProfile (object, optional): User profile data from OAuth redirect.-
refreshToken (string, optional): Pinterest refresh token if available.-
expiresIn (integer, optional): Token expiration time in seconds.-
redirect_url (string, optional): Custom redirect URL after connection completes.- Responses:
-
200: Pinterest Board connected successfully, returns a message and account details.-
400: Missing required fields.-
401: Unauthorized access.-
403: No access to profile or profile limit exceeded.-
500: Failed to save Pinterest connection.Improvement
GET /v1/accounts/{accountId}/linkedin-mentions
This endpoint resolves a LinkedIn profile URL (for a person) or a company page URL (for an organization) to a URN that can be used to @mention them in posts.
Parameters:
-
-
- Person:
- Organization:
-
Response:
On success (HTTP 200), the response contains:
-
-
-
-
-
-
This change allows developers to mention organizations without needing to be an admin of a LinkedIn organization, which simplifies the process of tagging companies in posts. Person mentions still require admin access for the organization but now support a broader range of input formats.
This endpoint resolves a LinkedIn profile URL (for a person) or a company page URL (for an organization) to a URN that can be used to @mention them in posts.
Parameters:
-
accountId (path, required): The LinkedIn account ID.-
url (query, required): LinkedIn profile URL, company URL, or vanity name. It supports:- Person:
miquelpalet, linkedin.com/in/miquelpalet- Organization:
company/microsoft, linkedin.com/company/microsoft-
displayName (query, optional): The exact display name as shown on LinkedIn. This is required for clickable person mentions. If not provided, the name is derived from the vanity URL, which may not match exactly.Response:
On success (HTTP 200), the response contains:
-
urn: The LinkedIn URN (either for a person or organization).-
type: The type of entity, which can be either person or organization.-
displayName: The display name (provided, from API, or derived from vanity URL).-
mentionFormat: Ready-to-use mention format for post content.-
vanityName: The vanity name/slug (only for organization mentions).-
warning: A warning about clickable mentions (only present for person mentions if displayName was not provided).This change allows developers to mention organizations without needing to be an admin of a LinkedIn organization, which simplifies the process of tagging companies in posts. Person mentions still require admin access for the organization but now support a broader range of input formats.
Improvement
GET /v1/profiles
This endpoint lists profiles visible to the authenticated user. It now includes a new optional query parameter
Response contains:
-
-
-
-
-
-
-
GET /v1/accounts
This endpoint lists connected social accounts. It now also includes the
Response contains:
-
-
-
-
-
-
-
-
-
This endpoint lists profiles visible to the authenticated user. It now includes a new optional query parameter
includeOverLimit (type: boolean, default: false). When set to true, it includes profiles that exceed the user's plan limit, which will have isOverLimit: true in the response. This is useful for managing or deleting profiles after a plan downgrade. The profiles are sorted by creation date (oldest first).Response contains:
-
profiles: an array of profile objects, each containing:-
id: string-
name: string-
color: string-
isDefault: boolean-
isOverLimit: boolean (only present when includeOverLimit=true)-
createdAt: string (date-time)GET /v1/accounts
This endpoint lists connected social accounts. It now also includes the
includeOverLimit parameter (type: boolean, default: false). When true, it includes accounts from profiles that exceed the user's plan limit, allowing users to disconnect accounts from over-limit profiles for deletion.Response contains:
-
accounts: an array of account objects, each containing:-
id: string-
platform: string-
profileId: object containing profile details-
username: string-
displayName: string-
profileUrl: string-
isActive: boolean-
hasAnalyticsAccess: boolean (indicates if the user has analytics add-on access)Improvement
The
-
-
-
These fields help you understand why an account was disconnected and quickly look up related data.
account.disconnected webhook payload now includes additional fields for better context:-
accountId - The account's unique identifier (same as used in /v1/accounts/{accountId})-
profileId - The profile's unique identifier this account belongs to-
disconnectionType - Either intentional (user disconnected manually) or unintentional (token expired or was revoked)These fields help you understand why an account was disconnected and quickly look up related data.