The Zernio MCP connector routes your AI agent's tool calls to Zernio's own MCP server through Scalekit. Each user signs in to Zernio once, and Scalekit stores and refreshes their tokens, so your agent never handles credentials. It comes with 54 tools.
- Tools
- 54
- What they doRead · write · destructive
- 29 · 0 · 2529 read0 write25 destructive
- Users sign in with
- OAuth
- OAuth app
- Your own Zernio MCP server app
Setup
Install the SDK
Terminal window npm install @scalekit-sdk/node dotenvTerminal window pip install scalekit-sdk-python python-dotenvSet your credentials
Add your Scalekit credentials to your
.envfile. Find values in app.scalekit.com > Developers > API Credentials..env SCALEKIT_ENVIRONMENT_URL=<your-environment-url>SCALEKIT_CLIENT_ID=<your-client-id>SCALEKIT_CLIENT_SECRET=<your-client-secret>Create the Zernio MCP connection
In AgentKit > Connections, create a Zernio MCP connection and copy its redirect URI. The name you give it is the
connection_nameyour code passes. See Configure connections.Register an OAuth app
Zernio MCP server connections use your own OAuth app. Register one with Zernio MCP server and add the redirect URI you copied.
Then enter the app's Client ID and Client Secret on the Zernio MCP connection.
Authorize a user and make your first call
quickstart.mts import { ScalekitClient } from '@scalekit-sdk/node'import 'dotenv/config'import { createInterface } from 'node:readline/promises'const scalekit = new ScalekitClient(process.env.SCALEKIT_ENVIRONMENT_URL,process.env.SCALEKIT_CLIENT_ID,process.env.SCALEKIT_CLIENT_SECRET,)const actions = scalekit.actionsconst connector = 'zerniomcp'const identifier = 'user_123'// Generate an authorization link for the userconst { link } = await actions.getAuthorizationLink({ connectionName: connector, identifier })console.log('Authorize Zernio MCP:', link)const rl = createInterface({ input: process.stdin, output: process.stdout })await rl.question('Press Enter after authorizing...')rl.close()// Make your first callconst result = await actions.executeTool({connector,identifier,toolName: 'zerniomcp_account_groups_list_account_groups',toolInput: {},})console.log(result)Terminal window npx tsx quickstart.mtsquickstart.py import osfrom scalekit import ScalekitClientfrom dotenv import load_dotenvload_dotenv()scalekit_client = ScalekitClient(env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),client_id=os.getenv("SCALEKIT_CLIENT_ID"),client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),)actions = scalekit_client.actionsconnection_name = "zerniomcp"identifier = "user_123"# Generate an authorization link for the userlink_response = actions.get_authorization_link(connection_name=connection_name,identifier=identifier,)print("Authorize Zernio MCP:", link_response.link)input("Press Enter after authorizing...")# Make your first callresult = actions.execute_tool(tool_input={},tool_name="zerniomcp_account_groups_list_account_groups",connection_name=connection_name,identifier=identifier,)print(result)Terminal window python quickstart.pyEach user signs in once. See Authorize a user for the full flow and statuses.
Tools
Pass the exact name toexecute_toolzerniomcp_account_groups_list_account_groupsList groups Returns all account groups visible to the authenticated user.Read-onlyList groups
List groups Returns all account groups visible to the authenticated user. Groups can contain accounts from multiple profiles. For API keys scoped to specific profiles, only groups whose accounts all live in allowed profiles are returned.
Inputs
This tool takes no inputs.
zerniomcp_accounts_getGet account details for a specific platform.Read-onlyGet account details for a specific platform
Get account details for a specific platform. Returns username and ID for the first account matching the platform.
Inputs
platformstringrequired- Platform name: twitter, instagram, linkedin, tiktok, bluesky, facebook, youtube, pinterest, threads (required)
zerniomcp_accounts_get_account_healthCheck account health Returns detailed health info for a specific account including token status, permissions, and recommendations.Read-onlyCheck account health
Check account health Returns detailed health info for a specific account including token status, permissions, and recommendations. A failing or stalled analytics sync (see `analyticsSync`) raises a healthy account to at least `warning`. ### Facebook, Instagram and Threads The token is also probed live. A probe Meta refuses with a dead-token error sets `tokenStatus.valid` to `false` and names Meta's code, subcode and fbtrace in `issues`. The exception: if an analytics sync succeeded with that token in the last six hours, the token stays `valid` and `issues` reports the probe as inconclusive, since Meta answers a transient 190 to live tokens now and then. Neither verdict disconnects the account. That happens only when a real operation fails, and `account.disconnected` is sent. ### WhatsApp The response also includes `platformConnection`, a live probe of the Meta link behind the channel (the same read as `GET /v1/whatsapp/number-info`). The OAuth token can be perfectly valid while Meta refuses to ...
Inputs
account_idstringrequired- The account ID to check (required)
zerniomcp_accounts_get_all_accounts_healthCheck accounts health Returns health status of all connected accounts including token validity, permissions, and issues needing attention.Read-onlyCheck accounts health
Check accounts health Returns health status of all connected accounts including token validity, permissions, and issues needing attention. A failing or stalled analytics sync (see `analyticsSync`) raises a healthy account to at least warning.
Inputs
platformstring- Filter by platformone of
facebookinstagramlinkedintwittertiktokyoutubethreadspinterestredditblueskygooglebusinesstelegramsnapchatdiscordslackwhatsappshopifywordpresswixlinkedinadsmetaadspinterestadstiktokadsxadsgoogleadsopenaiadsredditadsmicrosoftadswhopadshubspotwebflowgoogleanalytics profile_idstring- Filter by profile ID
statusstring- Filter by health statusone of
healthywarningerror
zerniomcp_accounts_get_follower_statsGet follower stats Returns follower count history and growth metrics for connected accounts.Read-onlyGet follower stats
Get follower stats Returns follower count history and growth metrics for connected accounts. Requires analytics add-on subscription. Follower counts are refreshed once per day.
Inputs
account_idsstring- Comma-separated list of account IDs (optional, defaults to all user's accounts)
cursorstring- Opaque cursor from a previous response's `pagination.nextCursor`; returns the next page of `limit` accounts (25 when limit is omitted). A cursor we cannot parse returns 400.
from_datestring- Start date in YYYY-MM-DD format (defaults to 30 days ago)
granularitystring- Data aggregation levelone of
dailyweeklymonthlydefaultdaily limitinteger- Accounts per page, ordered by account id. Send it to page through accounts; the response then carries `pagination.nextCursor`. Without limit or cursor every matching account is returned.
profile_idstring- Filter by profile ID
to_datestring- End date in YYYY-MM-DD format (defaults to today)
zerniomcp_accounts_listList connected social media accounts, one page at a time.Read-onlyList connected social media accounts, one page at a time
List connected social media accounts, one page at a time. Returns the platform, username, and account ID for each account on the page. Use this to find account IDs needed for creating posts. In a large workspace filter by platform, profile_id or search instead of paging through everything.
Inputs
cursorstring- Cursor returned by the previous page. Keep the same filters Default: .default
limitinteger- Page size, up to 500 Default: 100.default
100 platformstring- Only accounts on this platform (e.g., 'twitter') Default: .default
profile_idstring- Only accounts in this profile Default: .default
searchstring- Text matched against account ID, username, display name and platform user ID Default: .default
zerniomcp_analytics_get_analyticsGet post analytics Returns analytics for posts.Read-onlyGet post analytics
Get post analytics Returns analytics for posts. With postId, returns a single post. Without it, returns a paginated list with overview stats. - Accepts both Zernio Post IDs and External Post IDs (auto-resolved). - fromDate defaults to 90 days ago if omitted, max range 366 days. - Single post lookups may return 202 (sync pending) or 424 (all platforms failed). - For follower stats, use /v1/accounts/follower-stats. ### LinkedIn personal accounts Analytics are only available for posts published through Zernio. LinkedIn's API only returns metrics for posts authored by the authenticated user. Organization/company page analytics work for all posts. ### Facebook Page stories Stories on a connected Page, published through Zernio or natively, are collected while they are live and returned like any other post (platformPostUrl points to the story). Metrics for a story published through Zernio are available on its Zernio post ID. Their lifetime metrics refresh about hourly, with a final reading shortly ...
Inputs
account_idstring- Filter by account ID. With a native postId, selects that account's copy of the post.
from_datestring- Inclusive lower bound (YYYY-MM-DD). Defaults to 90 days ago if omitted. Max range is 366 days.
limitinteger- Page size (default 50)default
50 orderstring- Sort orderone of
ascdescdefaultdesc pageinteger- Page number (default 1)default
1 platformstring- Filter by platform (default "all")
post_idstring- Returns analytics for a single post. Accepts Zernio Post IDs, External Post IDs and the platform's native post ID. Zernio IDs are auto-resolved to External Post analytics.
profile_idstring- Filter by profile ID (default "all"). With a native postId, selects that profile's copy of the post.
sort_bystring- Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views, website_clicks) sort a null value as 0.one of
dateengagementimpressionsreachlikescommentssharessavesclicksviewsfollowsig_reels_avg_watch_timeig_reels_video_view_total_timerepostsreels_skip_ratecompletion_rateprofile_viewswebsite_clicksdefaultdate sourcestring- Filter by post source: late (posted via Zernio API), external (synced from platform), all (default)one of
alllateexternaldefaultall tagsstring- Comma-separated tags (at most 20). Lists only posts created through Zernio that carry every listed tag, matched exactly and case-sensitively. Up to 200 published posts can match within the date range; more returns 400 asking to narrow fromDate and toDate. Ignored when postId is set.
to_datestring- Inclusive upper bound (YYYY-MM-DD). Defaults to today if omitted.
zerniomcp_analytics_get_best_time_to_postGet best times to post Returns the best times to post based on historical engagement data.Read-onlyGet best times to post
Get best times to post Returns the best times to post based on historical engagement data. Groups all published posts by day of week and hour (UTC), calculating average engagement per slot. Use this to auto-schedule posts at optimal times.
Inputs
account_idstring- Filter by account ID. Omit for all accounts.
platformstring- Filter by platform (e.g. "instagram", "tiktok"). Omit for all platforms.
profile_idstring- Filter by profile ID. Omit for all profiles.
sourcestring- Filter by post origin. "late" for posts published via Zernio, "external" for posts imported from platforms.one of
alllateexternaldefaultall
zerniomcp_analytics_get_daily_metricsGet daily aggregated metrics Returns daily aggregated analytics metrics and a per-platform breakdown.Read-onlyGet daily aggregated metrics
Get daily aggregated metrics Returns daily aggregated analytics metrics and a per-platform breakdown. Each day includes post count, platform distribution, and summed metrics (impressions, reach, likes, comments, shares, saves, clicks, views). Defaults to the last 180 days. `totals` sums the whole range for the applied filters (pass `accountId` for one account). With attribution "publish" they are the lifetime metrics of posts published in the range, with "received" the engagement that arrived in the range. Args: platform: Filter by platform (e.g. "instagram", "tiktok"). Omit for all platforms. profile_id: Filter by profile ID. Omit for all profiles. account_id: Filter by account ID from_date: Inclusive start date (ISO 8601). Defaults to 180 days ago. to_date: Inclusive end date (ISO 8601). Defaults to now. source: Filter by post origin. "late" for posts published via Zernio, "external" for posts imported from platforms. attribution: How each post's engagement is attributed to a day. - "publish" (default): sums each post's lifetime total on its publish date. - "received": buckets the per-day increase in engagement by the day it actually arrived (engagement-over-time), so engagement on older posts appears on the day it was gained rather than the post's publish date.
Inputs
account_idstring- Filter by account ID. Omit for all accounts.
attributionstring- How each post's engagement is attributed to a day. publish sums each post's lifetime total on its publish date. received buckets the per-day increase by the day it arrived.one of
publishreceiveddefaultpublish from_datestring- Inclusive start date. Omit to use the default range described in the tool description.
platformstring- Filter by platform, for example instagram or tiktok. Omit for all platforms.
profile_idstring- Filter by profile ID. Omit for all profiles.
sourcestring- Filter by post origin. late means posted via Zernio, external means synced from the platform, all returns both.one of
alllateexternaldefaultall to_datestring- Inclusive end date. Omit to use the current date.
zerniomcp_analytics_get_post_timelineGet post analytics timeline Returns a daily timeline of analytics metrics for a specific post, showing how impressions, likes, and other metrics evolved day-by-day since publishing.Read-onlyGet post analytics timeline
Get post analytics timeline Returns a daily timeline of analytics metrics for a specific post, showing how impressions, likes, and other metrics evolved day-by-day since publishing. Each row represents one day of data per platform. For multi-platform Zernio posts, returns separate rows for each platform. Args: post_id: The post to fetch timeline for. Accepts an ExternalPost ID, a platformPostId, or a Zernio Post ID. (required) from_date: Start of date range (ISO 8601). Defaults to 90 days ago. to_date: End of date range (ISO 8601). Defaults to now.
Inputs
post_idstringrequired- The post to fetch. Accepts a Zernio post ID, an external post ID or a platform-specific post ID.
from_datestring- Inclusive start date. Omit to use the default range described in the tool description.
to_datestring- Inclusive end date. Omit to use the current date.
zerniomcp_comments_get_inbox_post_commentsGet post comments Fetch comments for a specific post.Read-onlyGet post comments
Get post comments Fetch comments for a specific post. Requires accountId query parameter. ### Replies to a comment Pass `commentId` (Facebook, Instagram, Reddit, TikTok) to fetch replies to a specific comment instead of the post's top-level comments. - Facebook, Instagram and TikTok return the comment's replies, paged by `limit`/`cursor`. - Reddit returns the focused comment thread instead. - On Facebook and Instagram the requested comment itself comes back in the top-level `comment` field. On Facebook, passing a COMMENT id as `postId` (instead of using `commentId`) is also supported for backwards compatibility. It returns that comment's replies the same way. Prefer `commentId` for new integrations; it also works on Instagram, which rejects a comment id passed as `postId`. YouTube does not support either form: `postId` must be a video id. ### Caching Responses are cached for up to 10 minutes, so a page may lag new comments by that window. Do not poll this endpoint for real-time updates: ... Args: post_id: Zernio post ID or platform-specific post ID. Zernio IDs are auto-resolved. - **LinkedIn:** pass the post id exactly as the feed returns it (urn:li:share:<id> or urn:li:ugcPost:<id>). A bare number is read as an activity id (urn:li:activity:<n>, the number in a linkedin.com/feed/update URL), so a share or ugcPost number passed bare returns an empty list. - **Facebook:** a comment ID is also accepted and returns that comment's replies (kept for backwards compatibility). Prefer the `commentId` query parameter, which also works on Instagram. (required) account_id: (required) subreddit: (Reddit only) Subreddit name limit: Maximum number of comments to return cursor: Pagination cursor, returned by a previous call as `pagination.cursor`. This is the platform's own opaque paging value passed through verbatim: never construct, decode or validate it client-side. comment_id: (Facebook, Instagram, Reddit and TikTok) Get replies to a specific comment. On Facebook and Instagram, the requested comment is returned in the top-level `comment` field and comments[] holds its replies.
Inputs
account_idstringrequired- Filter by account ID. Omit for all accounts.
post_idstringrequired- The post to fetch. Accepts a Zernio post ID, an external post ID or a platform-specific post ID.
comment_idstring- Comment ID. For fetching, returns replies to that comment (Facebook, Instagram, Reddit and TikTok). For replying, replies to that specific comment.
cursorstring- Pagination cursor returned by a previous call. Pass it back verbatim.
limitinteger- Maximum number of items to return per page.default
25 subredditstring- (Reddit only) Subreddit name.
zerniomcp_comments_list_inbox_commentsList commented posts Returns posts with comment counts from all connected accounts.Read-onlyList commented posts
List commented posts Returns posts with comment counts from all connected accounts. Aggregates data across multiple accounts. ### Caching Responses are cached for up to 10 minutes, so the feed may lag new comments by that window. Do not poll this endpoint for real-time updates. Subscribe to the `comment.received` webhook, which fires for every new comment across your posts and carries the post reference needed to keep this list current. ### Meta ads For users with the Ads add-on (accounts on usage-based billing always qualify), the user's Meta ads (boosted/dark posts) are included too. There's one row per (ad, placement-with-comments). An ad that runs on both Facebook feed and Instagram feed produces up to two rows, since the Page dark post and the IG media have separate comment threads. Each ad row is flagged `isAd: true` with `adId` and `placement` (`id` is `{adId}:{placement}`). Filter with `platform`: - `?platform=metaads`: *only* ad rows. - `facebook`/`instagram`: *organic* posts only (no ... Args: profile_id: Filter by profile ID platform: Filter by platform. `metaads` is a synthetic value meaning the user's ads (boosted/dark posts) only; `facebook`/`instagram` return organic posts only. `tiktok` covers accounts connected through the TikTok Business app only; developer-app TikTok accounts are returned under `meta.accountsSkipped`. min_comments: Minimum comment count, applied to each page after pagination since: Posts created after this date sort_by: Sort field sort_order: Sort order limit cursor account_id: Filter by specific account ID. With `platform=metaads` it takes the Meta Ads account ID, or the Facebook or Instagram account ID the Meta Ads connection belongs to, which returns that connection's ad rows. A Facebook or Instagram account with no Meta Ads connection returns no rows. An account on any other platform returns 400.
Inputs
account_idstring- Filter by account ID. Omit for all accounts.
cursorstring- Pagination cursor returned by a previous call. Pass it back verbatim.
limitinteger- Maximum number of items to return per page.default
50 min_commentsinteger- Minimum comment count, applied to each page after pagination.
platformstring- Filter by platform. metaads returns only the user's ads; facebook and instagram return organic posts only.one of
facebookinstagramtwitterblueskythreadsyoutubelinkedinreddittiktokmetaads profile_idstring- Filter by profile ID. Omit for all profiles.
sincestring- Only posts created after this date (ISO 8601).
sort_bystring- Field to sort by.one of
datecommentsdefaultdate sort_orderstring- Sort order.one of
ascdescdefaultdesc
zerniomcp_docs_searchSearch across the Late API documentation to find relevant information, code examples, API references, and guides.Read-onlySearch the Late API documentation
Search across the Late API documentation to find relevant information, code examples, API references, and guides. Use this tool when you need to answer questions about Late, find specific documentation, understand how features work, or locate implementation details. The search returns contextual content with section titles and relevant snippets.
Inputs
querystringrequired- Search query (e.g., 'webhooks', 'create post', 'authentication') (required)
zerniomcp_media_check_upload_statusCheck the status of an upload token and get uploaded file URLs.Read-onlyCheck upload status and get file URLs
Check the status of an upload token and get uploaded file URLs. Use this after the user has uploaded files through the browser upload page. Returns: pending (waiting for upload), completed (files ready), or expired (token expired).
Inputs
tokenstringrequired- The upload token from media_generate_upload_link (required)
zerniomcp_mentions_list_inbox_mentionsList mentions Returns mentions of your connected accounts from the last 7 days.Read-onlyList mentions
List mentions Returns mentions of your connected accounts from the last 7 days. Requires Inbox addon. ### LinkedIn Organization mentions, delivered by webhooks and a background pull. ### Instagram Comment mentions (someone tags the account in a comment on their own media) and caption mentions (someone tags it in their media caption), delivered by the Meta `mentions` webhook. - Only accounts connected through Facebook Login receive them. - Comments on the account's own posts are never listed, even when they contain its @handle. - Their text is read from Instagram in the background after the first request, so `content` can be empty on the first read. - Pass `mediaId` and `commentId` to `POST /v1/inbox/mentions/reply` to answer one. ### Facebook Post mentions (someone tags the Page in a post) and comment mentions (someone tags it in a comment), delivered by the Page `mention` webhook with their text. - Comments on the Page's own posts and anything the Page wrote itself are never listed. - ...
Inputs
account_idstring- Filter by account ID
cursorstring- Cursor for pagination (ID of the last item from the previous page)
limitinteger- Maximum number of items to return per page.default
25 profile_idstring- Filter by profile ID
sort_orderstring- Sort order by publishedAtone of
ascdescdefaultdesc
zerniomcp_posts_getGet full details of a specific post including content, status, and scheduling info.Read-onlyGet details of a specific post
Get full details of a specific post including content, status, and scheduling info.
Inputs
post_idstringrequired- The post ID to retrieve (required)
zerniomcp_posts_listList posts with optional filtering by status.Read-onlyList posts with optional filtering
List posts with optional filtering by status. Status options: draft, scheduled, published, failed
Inputs
limitinteger- Maximum number of posts to return Default: 10.default
10 statusstring- Filter by status: draft, scheduled, published, failed. Leave empty for all posts Default: .default
zerniomcp_posts_list_failedList all failed posts that can be retried.Read-onlyList all failed posts
List all failed posts that can be retried.
Inputs
limitinteger- Maximum number of posts to return Default: 10.default
10
zerniomcp_profiles_getGet details of a specific profile including name, description, and color.Read-onlyGet details of a specific profile
Get details of a specific profile including name, description, and color.
Inputs
profile_idstringrequired- The profile ID (required)
zerniomcp_profiles_listList profiles, one page at a time.Read-onlyList profiles, one page at a time
List profiles, one page at a time. Profiles group multiple social accounts together for easier management.
Inputs
limitinteger- Page size, up to 1000 Default: 100.default
100 namestring- Only the profile with exactly this name Default: .default
skipinteger- How many profiles to skip, for the next page Default: 0.default
0
zerniomcp_queue_get_next_queue_slotGet next available slot Returns the next available queue slot for preview purposes.Read-onlyGet next available slot
Get next available slot Returns the next available queue slot for preview purposes. To create a queue post, use POST /v1/posts with queuedFromProfile instead of scheduledFor.
Inputs
profile_idstringrequired- (required)
queue_idstring- Specific queue ID (optional, defaults to profile's default queue)
zerniomcp_queue_list_queue_slotsList schedules Returns queue schedules for a profile.Read-onlyList schedules
List schedules Returns queue schedules for a profile. Use all=true for all queues, or queueId for a specific one. Defaults to the default queue.
Inputs
profile_idstringrequired- Profile ID to get queues for (required)
allstring- Set to 'true' to list all queues for the profile
queue_idstring- Specific queue ID to retrieve (optional)
zerniomcp_queue_preview_queuePreview upcoming slots Returns the next N upcoming queue slot times for a profile as ISO datetime strings.Read-onlyPreview upcoming slots
Preview upcoming slots Returns the next N upcoming queue slot times for a profile as ISO datetime strings.
Inputs
profile_idstringrequired- (required)
countinteger- No description.default
20 queue_idstring- Filter by specific queue ID. Omit to use the default queue.
zerniomcp_search_toolsSearch for tools using natural language.Read-onlySearch available tools
Search for tools using natural language. Returns matching tool definitions ranked by relevance, in the same format as list_tools.
Inputs
querystringrequired- Natural language query to search for tools
zerniomcp_support_assistant_get_support_answerGet a support answer Returns a run started by your team, with the answer once it is ready.Read-onlyGet a support answer
Get a support answer Returns a run started by your team, with the answer once it is ready. Prefer the `support.run.completed` and `support.run.failed` webhooks. Use this as the fallback, waiting `pollAfterSeconds` between polls. `costUsd` is the amount billed for the question, never above `maxCostUsd`, and 0 for a failed run (pricing on Ask a support question).
Inputs
run_idstringrequired- (required)
zerniomcp_usage_get_usageUsage snapshot (default) or billed-spend metering (with params) Dual-mode endpoint, selected by query params, and fully backward compatible.Read-onlyUsage snapshot (default) or billed-spend metering (with params)
Usage snapshot (default) or billed-spend metering (with params) Dual-mode endpoint, selected by query params, and fully backward compatible. ### Without metering params (the default) Returns the plan / quota / usage snapshot: plan name, billing period, limits, usage counts, access state. Identical to `GET /v1/usage-stats`. Existing integrations keep working unchanged. ### With `range`, `granularity`, `from`, or `to` Returns usage METERING: billed spend (USD) by product family over the window, at `day` / `month` / `total` granularity. Product families: `accounts`, `numbers`, `imessage`, `calls`, `sms`, `messages`, `verify`, `dlc`, `xApi`, `ads`, `credits`, `other`. Data comes from the usage-based invoice breakdown (the CHARGE view, which always reconciles with what gets billed). Also served at `GET /v1/usage/daily`. Usage-based accounts only: legacy Stripe accounts get `{ "supported": false, "days": [] }`. ### Attribution (metering mode) `groupBy=profile|account` adds an `attribution` breakdown of the window's spend per profile or account. ... Args: reconcile: Snapshot mode only. For Stripe subscription users, `true` forces a subscription reconciliation pass even when cached plan data looks complete. range: Window to report. `cycle` / `prev-cycle` resolve to the customer's real billing-period bounds (falling back to a trailing 30 days when no invoice exists yet); `7d`…`12mo` are trailing windows; `custom` uses `from` / `to`. from_: Inclusive start (UTC date). Required when `range=custom`. to: Inclusive end (UTC date). Required when `range=custom`. Max span 366 days. granularity: Bucketing of the `days` series: `day` (one row per UTC day), `month` (one row per calendar month, dated to the 1st), or `total` (no series, read `totals`). Does not affect `totals`. group_by: Metering mode. Adds `attribution`: the window's spend split per profile or per account (keys are ids; resolve names via `GET /v1/profiles` / `GET /v1/accounts`). profile_id: Metering mode (pair with `range`). Project the payload onto this profile's attributed share. Mutually exclusive with `accountId`, and `groupBy` (if given) must be `profile`; 404 when the profile is not in your team (or outside a scoped key's profiles). account_id: Metering mode (pair with `range`). Project the payload onto this account's attributed share. Mutually exclusive with `profileId`, and `groupBy` (if given) must be `account`; 404 when the account is not visible to the caller.
Inputs
account_idstring- Metering mode (pair with range). Project the payload onto this account's attributed share. Mutually exclusive with profile_id; group_by (if given) must be account.
from_string- Inclusive start (UTC date). Required when range is custom.
granularitystring- Bucketing of the days series: day (one row per UTC day), month (one row per calendar month, dated to the 1st), or total (no series, read totals). Does not affect totals.one of
daymonthtotaldefaultday group_bystring- Metering mode. Adds attribution: the window spend split per profile or per account.
profile_idstring- Metering mode (pair with range). Project the payload onto this profile's attributed share. Mutually exclusive with account_id; group_by (if given) must be profile.
rangestring- Window to report. cycle and prev-cycle resolve to the real billing-period bounds (falling back to a trailing 30 days when no invoice exists yet); 7d to 12mo are trailing windows; custom uses from_ and to.one of
cycleprev-cycle7d14d30d3mo12mocustomdefaultcycle reconcilestring- Snapshot mode only. For Stripe subscription users, true forces a subscription reconciliation pass even when cached plan data looks complete.
tostring- Inclusive end (UTC date). Required when range is custom. Max span 366 days.
zerniomcp_zernio_overviewShow an overview of what this Zernio MCP server can do (accounts, posts, analytics, ads, inbox) and how to find the right tool.Read-onlyZernio server overview
Show an overview of what this Zernio MCP server can do (accounts, posts, analytics, ads, inbox) and how to find the right tool.
Inputs
This tool takes no inputs.
zerniomcp_accounts_move_account_to_profileMove account to another profile Moves a connected account to a different profile owned by the same user.DestructiveMove account to another profile
Move account to another profile Moves a connected account to a different profile owned by the same user. The target profile must belong to the same user as the account. For API keys restricted to specific profiles, BOTH the source account's current profile AND the target profile must be in the key's allowed set. Calls with a target profile outside the key's scope return 403.
Inputs
account_idstringrequired- (required)
profile_idstringrequired- Target profile ID (must be a valid ObjectId and owned by the same user as the account). (required)
zerniomcp_call_toolCall a tool by name with the given arguments.DestructiveCall a tool discovered via search
Call a tool by name with the given arguments. Use this to execute tools discovered via search_tools.
Inputs
namestringrequired- The name of the tool to call
argumentsstring- Arguments to pass to the tool
zerniomcp_comments_reply_to_inbox_postReply to comment Post a reply to a post or specific comment.DestructiveReply to comment
Reply to comment Post a reply to a post or specific comment. Requires accountId in request body. ### Idempotency Send an `Idempotency-Key` header to make retries safe (e.g. after a client-side timeout where delivery is unknown). - Same key + same body replays the original response (with `Idempotent-Replayed: true`) instead of posting the comment a second time. - Same key + different body returns 422. - A key still in flight returns 409. Keys are retained for 24 hours and are scoped to the credential and to this exact path. Reusing a key against a different postId returns 422 rather than replaying the other post's response. Only successful (2xx) responses are stored for replay. If the request throws or returns a non-2xx status the key is released, so the header protects the "request succeeded but the response was lost" case. After an ambiguous failure (a 5xx or a network timeout), list the post's comments before retrying with the same key. Treat an empty result as inconclusive rather than as ...
Inputs
account_idstringrequired- (required)
messagestringrequired- Reply text. On LinkedIn, mention with @[https://www.linkedin.com/in/vanity] (resolved to LinkedIn's live name, same rules and errors as post content) or @[Name](urn:li:person|organization:ID); a hand-written name must match LinkedIn's exactly or it renders as plain text. (required)
post_idstringrequired- Zernio post ID or platform-specific post ID. On LinkedIn, pass the post id exactly as the feed returns it (urn:li:share:<id> or urn:li:ugcPost:<id>); a bare number is read as an activity id (urn:li:activity:<n>). (required)
attachment_urlstring- (Facebook only) URL of an image to attach, publishing a photo comment alongside the text. The URL must be publicly accessible so Meta can fetch it. Returns 400 for other platforms.
comment_idstring- Reply to specific comment (optional)
parent_cidstring- (Bluesky only) Parent content identifier
root_cidstring- (Bluesky only) Root post CID
root_uristring- (Bluesky only) Root post URI
zerniomcp_media_generate_upload_linkGenerate a unique upload URL for the user to upload files via browser.DestructiveGenerate an upload URL for media files
Generate a unique upload URL for the user to upload files via browser. Use this when the user wants to include images or videos in their post. The flow is: 1. Call this tool to get an upload URL 2. Ask the user to open the URL in their browser 3. User uploads files through the web interface 4. Call media_check_upload_status to get the uploaded file URLs 5. Use those URLs when creating the post with posts_create
Inputs
This tool takes no inputs.
zerniomcp_mentions_reply_to_mentionReply to a mention Reply to a mention of the connected account.DestructiveReply to a mention
Reply to a mention Reply to a mention of the connected account. Supported on Instagram only. Two shapes, selected by whether `commentId` is present: - **Comment mention** (someone @mentioned the account inside a comment): pass both `mediaId` and `commentId`. Instagram posts a reply under that comment. - **Caption mention** (someone @mentioned the account in their media caption, so no comment exists): pass `mediaId` only. Instagram posts a comment on their media. Story mentions are not supported by Instagram's API. `GET /v1/inbox/mentions` returns Instagram mentions with the `mediaId` and `commentId` to pass here.
Inputs
account_idstringrequired- The Instagram account ID (required)
media_idstringrequired- The ID of the media the account was mentioned in (required)
messagestringrequired- The reply text (required)
comment_idstring- The mentioning comment's ID. Omit for a caption mention.
zerniomcp_posts_bulk_upload_postsBulk upload from CSV Create multiple posts by uploading a CSV file.DestructiveBulk upload from CSV
Bulk upload from CSV Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts. ### Required columns - `platforms`, `profiles`, and a schedule: one of `schedule_time`, a `schedule_time_<platform>` override, `publish_now=true`, `use_queue=true`, or `is_draft=true`. - Content: at least one of `post_content`, `title`, or `media_urls`. ### Aliases A handful of columns accept the JSON field name from POST /v1/posts, since integrators infer the CSV shape from that endpoint's body. When both are present the real CSV column wins, unless it is blank for that row, in which case the alias value is used. - `content` aliases `post_content` - `timezone` aliases `tz` - `scheduledFor` aliases `schedule_time` - `mediaUrls` aliases `media_urls` ### Per-platform overrides Three dynamic column prefixes, one column per platform (e.g. `schedule_time_instagram`, `custom_content_tiktok`, `custom_media_youtube`): - `schedule_time_<platform>` - `custom_content_<platform>` - ... Args: dry_run
Inputs
dry_runboolean- No description.default
false
zerniomcp_posts_createCreate a social media post.DestructiveCreate a social media post (draft, scheduled, or immediate)
Create a social media post. Can be saved as DRAFT, SCHEDULED, or PUBLISHED immediately. ⚠️ IMPORTANT - Choose the correct mode based on user intent: **DRAFT MODE (is_draft=True)** Use when user says: "draft", "borrador", "save for later", "don't publish", "save it", "guardar" → Post is saved but NOT published and NOT scheduled. User can edit it later. **IMMEDIATE MODE (publish_now=True)** Use when user says: "publish now", "post now", "publica ya", "immediately", "right now", "ahora" → Post goes live IMMEDIATELY. **SCHEDULED MODE (default)** Use when user says: "schedule", "programar", "in X minutes/hours", "at 3pm", "tomorrow" → Post is scheduled for future publication. Use schedule_minutes to set the delay. ⚠️ MULTI-ACCOUNT USERS (agencies, multi-client setups): If the user has more than one account on the target platform, you MUST pass `account_id`. Call `accounts_list` (or `profiles_list` then `accounts_list`) first to discover the right ID. If you omit account_id when multiple accounts exist, the tool returns an error listing the candidates - use it to retry. Examples: - "Create a draft tweet" → is_draft=True - "Post this to Twitter now" → publish_now=True - "Schedule a LinkedIn post for 2 hours from now" → schedule_minutes=120 - "Post this to Acme's Twitter" → call accounts_list, find Acme's twitter ID, pass account_id
Inputs
contentstringrequired- The post text/content (required)
platformstringrequired- Target platform: twitter, instagram, linkedin, tiktok, bluesky, facebook, youtube, pinterest, threads (required)
account_idstring- Specific account ID to post from. REQUIRED when the user has multiple accounts on this platform. Call accounts_list first to find IDs. Leave empty only if there is exactly one account for this platform. Default: .default
is_draftboolean- Set to True to save as DRAFT (not published, not scheduled). Use when user wants to save without publishing Default: False.default
false media_urlsstring- Comma-separated URLs of media files to attach (images, videos) Default: .default
profile_idstring- Scope account resolution to one profile (e.g. one client in an agency setup). Use when account_id is unknown but the target profile is. Call profiles_list to find IDs. Default: .default
publish_nowboolean- Set to True to publish IMMEDIATELY. Post goes live right now Default: False.default
false schedule_minutesinteger- Minutes from now to schedule. Only used when is_draft=False AND publish_now=False Default: 60.default
0 titlestring- Post title (required for YouTube, recommended for Pinterest) Default: .default
zerniomcp_posts_cross_postPost the same content to multiple platforms at once.DestructivePost the same content to multiple platforms
Post the same content to multiple platforms at once. ⚠️ IMPORTANT - Choose the correct mode based on user intent: **DRAFT MODE (is_draft=True)** Use when user says: "draft", "borrador", "save for later", "don't publish" → Posts are saved but NOT published. User can edit them later. **IMMEDIATE MODE (publish_now=True)** Use when user says: "publish now", "post now", "immediately" → Posts go live IMMEDIATELY on all platforms. **SCHEDULED MODE (default)** Use when user says: "schedule", "programar", "in X hours" → Posts are scheduled for 1 hour from now. ⚠️ MULTI-ACCOUNT USERS: - To pick a specific account per platform, pass `account_ids` parallel to `platforms` (same order, comma-separated). Use empty string for a position to fall back to profile/auto-resolution. - To target multiple accounts of the SAME platform in one call, repeat the platform: platforms='twitter,twitter', account_ids='acc_a,acc_b'. - If you omit account_ids and the user has multiple accounts for any of the requested platforms, the tool errors with the candidate list - use it to retry.
Inputs
contentstringrequired- The post text/content (required)
platformsstringrequired- Comma-separated list of platforms (e.g., 'twitter,linkedin,bluesky'). Repeat a platform to target multiple accounts of it: 'twitter,twitter'. (required)
account_idsstring- Comma-separated account IDs, parallel to `platforms`. Empty positions fall back to profile/auto-resolution. Required for multi-account users to disambiguate. Default: .default
is_draftboolean- Set to True to save as DRAFT (not published). Use when user wants to save without publishing Default: False.default
false media_urlsstring- Comma-separated URLs of media files to attach Default: .default
profile_idstring- Scope auto-resolution to one profile when account_ids is empty. Default: .default
publish_nowboolean- Set to True to publish IMMEDIATELY to all platforms Default: False.default
false
zerniomcp_posts_deleteDelete a post by ID.DestructiveDelete a post
Delete a post by ID. Published posts cannot be deleted.
Inputs
post_idstringrequired- The post ID to delete (required)
zerniomcp_posts_edit_postEdit published post Edit the text of an already-published post.DestructiveEdit published post
Edit published post Edit the text of an already-published post. Supported on X, Discord, Facebook, Reddit, LinkedIn, Telegram, Pinterest, Google Business Profile, YouTube, and Slack. When a post was published to several accounts on the same platform, pass `accountId` to pick which account's copy to edit (without it the request returns 409). Each platform enforces its own rules. **X** - Connected X account must have an active X Premium subscription - Must be within 1 hour of original publish time - Maximum 5 edits per tweet (enforced by X) - Threads cannot be edited, only single tweets - X assigns a NEW post ID on edit, returned as `id` **Discord** - No time limit and no premium requirement - The message ID is unchanged after the edit **Facebook** - Graph only permits editing a post that the same app created. This works on posts published through Zernio and is rejected for posts created in Meta Business Suite / Composer or by another tool - Media cannot be swapped, only the message text - ...
Inputs
contentstringrequired- The new post text content (required)
platformstringrequired- The platform to edit the post on. (required)one of
twitterdiscordfacebookredditlinkedintelegrampinterestgooglebusinessyoutubeslack post_idstringrequired- (required)
account_idstring- Which account's copy of the post to edit when the post was published to several accounts on the same platform. Required in that case.
zerniomcp_posts_publish_nowPublish a post immediately to a platform.DestructivePublish a post immediately
Publish a post immediately to a platform. The post goes live right away. Use this when user explicitly wants to publish NOW, not schedule for later. This is a convenience wrapper around posts_create with publish_now=True. ⚠️ MULTI-ACCOUNT USERS: pass `account_id` when the user has more than one account on this platform. Call `accounts_list` first to find the right ID.
Inputs
contentstringrequired- The post text/content (required)
platformstringrequired- Target platform: twitter, instagram, linkedin, tiktok, bluesky, etc. (required)
account_idstring- Specific account ID. REQUIRED when the user has multiple accounts on this platform. Leave empty only if there is exactly one. Default: .default
media_urlsstring- Comma-separated URLs of media files to attach Default: .default
profile_idstring- Scope auto-resolution to a single profile when account_id is unknown. Default: .default
zerniomcp_posts_retryRetry publishing a failed post.DestructiveRetry a failed post
Retry publishing a failed post. Only works on posts with 'failed' status.
Inputs
post_idstringrequired- The ID of the failed post to retry (required)
zerniomcp_posts_retry_all_failedRetry all failed posts at once.DestructiveRetry all failed posts
Retry all failed posts at once.
Inputs
This tool takes no inputs.
zerniomcp_posts_unpublish_postUnpublish post Deletes a published post from the specified platform.DestructiveUnpublish post
Unpublish post Deletes a published post from the specified platform. The post record in Zernio is kept but its status is updated to cancelled. Not supported on Instagram, TikTok, or Snapchat. Threaded posts delete all items. YouTube deletion is permanent.
Inputs
platformstringrequired- The platform to delete the post from (required)one of
threadsfacebooktwitterlinkedinyoutubepinterestredditblueskygooglebusinesstelegram post_idstringrequired- (required)
account_idstring- Which account's copy to delete when the post was published to several accounts on this platform. Required in that case.
zerniomcp_posts_updateUpdate an existing post.DestructiveUpdate an existing post
Update an existing post. Only draft, scheduled, and failed posts can be updated. Published posts cannot be modified.
Inputs
post_idstringrequired- The post ID to update (required)
contentstring- New content (leave empty to keep current) Default: .default
scheduled_forstring- New schedule time as ISO string (leave empty to keep current) Default: .default
titlestring- New title (leave empty to keep current) Default: .default
zerniomcp_profiles_createCreate a new profile for grouping social accounts.DestructiveCreate a new profile
Create a new profile for grouping social accounts.
Inputs
namestringrequired- Profile name (required)
colorstring- Optional hex color (e.g., '#4CAF50') Default: .default
descriptionstring- Optional description Default: .default
zerniomcp_profiles_deleteDelete a profile.DestructiveDelete a profile
Delete a profile. The profile must have no connected accounts.
Inputs
profile_idstringrequired- The profile ID to delete (required)
zerniomcp_profiles_updateUpdate an existing profile.DestructiveUpdate an existing profile
Update an existing profile. Only provided fields will be changed.
Inputs
profile_idstringrequired- The profile ID to update (required)
colorstring- New hex color (leave empty to keep current) Default: .default
descriptionstring- New description (leave empty to keep current) Default: .default
is_defaultboolean- Set as default profile Default: False.default
false namestring- New name (leave empty to keep current) Default: .default
zerniomcp_queue_create_queue_slotCreate schedule Create an additional queue for a profile.DestructiveCreate schedule
Create schedule Create an additional queue for a profile. The first queue created becomes the default. Subsequent queues are non-default unless explicitly set.
Inputs
namestringrequired- Queue name (e.g., Evening Posts) (required)
profile_idstringrequired- Profile ID (required)
slotsstringrequired- Each item is an object with keys: dayOfWeek (integer) - Day of week (0=Sunday, 6=Saturday); time (string) - Time in HH:mm format (24-hour) (required)
timezonestringrequired- IANA timezone (required)
activeboolean- No description.default
true
zerniomcp_queue_delete_queue_slotDelete schedule Delete a queue from a profile.DestructiveDelete schedule
Delete schedule Delete a queue from a profile. Pass queueId to delete a specific queue; omit it to delete all queues for the profile. If deleting the default queue, another queue will be promoted to default.
Inputs
profile_idstringrequired- (required)
queue_idstring- Queue ID to delete. Omit to delete all queues for the profile
zerniomcp_queue_update_queue_slotUpdate schedule Create a new queue or update an existing one.DestructiveUpdate schedule
Update schedule Create a new queue or update an existing one. Without queueId, creates/updates the default queue. With queueId, updates a specific queue. With setAsDefault=true, makes this queue the default for the profile.
Inputs
profile_idstringrequired- (required)
slotsstringrequired- Each item is an object with keys: dayOfWeek (integer) - Day of week (0=Sunday, 6=Saturday); time (string) - Time in HH:mm format (24-hour) (required)
timezonestringrequired- (required)
activeboolean- No description.default
true namestring- Queue name
queue_idstring- Queue ID to update (optional)
reshuffle_existingboolean- Whether to reschedule existing queued posts to match new slotsdefault
false set_as_defaultstring- Make this queue the default
zerniomcp_support_askAsk Zernio's Support Assistant to diagnose a problem with the user's Zernio workspace.DestructiveAsk Zernio's Support Assistant to diagnose a problem (paid)
Ask Zernio's Support Assistant to diagnose a problem with the user's Zernio workspace. PAID: typically $0.10 to $0.50 per question, never more than max_cost_usd. Failed questions are free. Use this once per unexplained Zernio API error, after docs_search did not explain it. Never loop or retry: identical arguments return the same run, not a new one. For a follow-up, pass thread_id from the previous answer. Requires an unrestricted Zernio API key. OAuth connectors (claude.ai, ChatGPT) and restricted or profile-scoped keys cannot use it. If the answer is not ready within wait_seconds, the result carries the runId; fetch it later with support_assistant_get_support_answer.
Inputs
questionstringrequired- The problem to diagnose, with the error message and what was attempted (required)
account_idstring- Account the assistant should look atdefault
max_cost_usdnumber- Cost cap in USD for this question (0.5 to 3) Default: 1.0.default
1 post_idstring- Post the assistant should look atdefault
profile_idstring- Profile the assistant should look atdefault
thread_idstring- Continue an earlier conversation (threadId from a previous answer)default
wait_secondsinteger- How long to wait for the answer before returning the run id (0 to 120) Default: 45.default
45
zerniomcp_validate_mediaValidate media URL Check if a media URL is accessible and return metadata (content type, file size) plus per-platform size limit comparisons.DestructiveValidate media URL
Validate media URL Check if a media URL is accessible and return metadata (content type, file size) plus per-platform size limit comparisons. Performs a HEAD request (with GET fallback) to detect content type and size. Rejects private/localhost URLs for SSRF protection. Platform limits are sourced from each platform's actual upload constraints.
Inputs
urlstringrequired- Public media URL to validate (required)
zerniomcp_validate_postValidate post content Dry-run the full post validation pipeline without publishing.DestructiveValidate post content
Validate post content Dry-run the full post validation pipeline without publishing. Catches issues like missing media for Instagram/TikTok/YouTube, hashtag limits, invalid thread formats, Facebook Reel requirements, and character limit violations. Accepts the same body as POST /v1/posts. Does NOT validate accounts, process media, or track usage. Account lookups are limit-only: a twitter accountId is resolved, scoped to the caller, only to pick the 280 vs 25000 character limit. Missing, foreign, or invalid ids fall back to 280 and never error. Returns errors for failures and warnings for near-limit content (>90% of character limit).
Inputs
platformsstringrequired- Target platforms (same format as POST /v1/posts) Each item is an object with keys: platform (one of: twitter, instagram, tiktok, youtube, facebook, linkedin, bluesky, threads, reddit, pinterest, telegram, snapchat, googlebusiness, discord, slack; required); accountId (string) - Account to validate against. For twitter, resolves X Premium status to apply the 25000 character limit instead of 280.; customContent (string); platformSpecificData (object); customMedia (list of objects with keys type, url, fileId, accountId, title, altText, filename, size, mimeType, thumbnail, instagramThumbnail, subtitles, tiktokProcessed) (required)
contentstring- Post text content
media_itemsstring- Root media items shared across platforms Each item is an object with keys: type (one of: image, video, gif, document) - Optional when the item names a connected file (`fileId`): inferred from the file's MIME type.; url (string) - A media item with a null, missing or empty url is dropped, unless it names a connected file with `fileId` + `accountId`.; fileId (string) - A file of a connected Google Drive or OneDrive account (see the Files endpoints). Requires `accountId`. The file is copied into Zernio media storage when the ...; accountId (string) - The connected Google or Microsoft account the `fileId` belongs to (must have the `files` area). Required with `fileId`.; title (string) - Optional title for the media item. Used as the document title for LinkedIn PDF/carousel posts. If omitted, falls back to the post title, then the filename.; altText (string) - Accessibility alternative text for an image. Set once per image; the same value is sent to each selected platform. - Applied on: Instagram (feed images only, ...; filename (string); size (integer) - Optional file size in bytes; mimeType (string) - Optional MIME type (e.g. image/jpeg, video/mp4); thumbnail (string) - Optional custom thumbnail/cover image URL for videos. Supported for Facebook video posts, Facebook Reels, YouTube videos and Shorts, and LinkedIn video posts. ...; instagramThumbnail (string) - Custom cover image URL for Instagram Reels. Can also be set via platformSpecificData.instagramThumbnail or platformSpecificData.reelCover. Resolution order: ...; subtitles (list of objects with keys url, language) - Subtitle (closed caption) files for a video item, in SRT or WebVTT. Each language may appear once per video. Zernio downloads each file when the post is ...; tiktokProcessed (boolean) - Internal flag indicating the image was resized for TikTok
zerniomcp_validate_post_lengthValidate character count Check weighted character count per platform and whether the text is within each platform's limit.DestructiveValidate character count
Validate character count Check weighted character count per platform and whether the text is within each platform's limit. Returns counts and limits for all 15 supported platform variants. ### Counting - X uses weighted counting (URLs = 23 chars via t.co, emojis = 2 chars). - All other platforms use plain character length. ### X rows X returns two rows, and this endpoint cannot tell you which one applies to you: it takes only `text`, so it never resolves an account. - `twitter` (280) is the free tier limit. - `twitterPremium` (25000) applies only when the target X account has a paid X subscription. Publishing enforces 280 instead for any post carrying a poll. This endpoint has no poll input, so the `twitterPremium` row always shows 25000. A free account trusting the `twitterPremium` row can pass validation here and still fail at publish time, where the account's real limit is enforced. ### Per-account limits To validate against the per-account limit, use `POST /v1/tools/validate/post` instead. It ...
Inputs
textstringrequired- The post text to check (required)
No tools match.