---
canonical_url: "https://docs.composio.dev/toolkits/metricool_mcp"
markdown_url: "https://docs.composio.dev/toolkits/metricool_mcp.md"
product: "platform"
version: null
last_updated: null
---

# Metricool MCP

Analyze social media performance, inspect scheduled posts, identify optimal publishing times, and create or update scheduled content through Metricool's official hosted MCP server.

- **Category:** social media marketing
- **Auth:** DCR_OAUTH
- **Composio-managed OAuth available?** No
- **Tools:** 9
- **Triggers:** 0
- **Slug:** `METRICOOL_MCP`
- **Version:** 00000000_00

## Tools

### Create scheduled post

**Slug:** `METRICOOL_MCP_CREATE_SCHEDULED_POST`

    Schedule a post to Metricool at a specific date and time.
    To be able to schedule the post, you need to maintain the structure.
    You can use the tool getBestTimeToPostByNetwork to get the best time to post for a specific provider if the user doesn't specify the time to post.
    If the post include Instagram, is a must to have at least one image or video. Posts must include an image or a carousel, Reels and Trial Reels must include a video, and Stories can include either an image or a video. If you don't have more information, you can ask the user about it and wait until you have the information.
    If the post include Pinterest, is a must to have a image and the board where to publish the pin. If you don't have more information, you can ask the user about it and wait until you have the information.
    If the post include Youtube, is a must to have a video, select the audience (if it's video made for kids or not) and the title of the video. If you don't have more information, you can ask the user about it and wait until you have the information.
    If the post include Tiktok, is a must to have at least one image or video. If you don't have more information, you can ask the user about it and wait until you have the information.
    If the post is Facebook Reel, is a must to have a video. If is Facebook Story, image or video is needed. If you don't have more information, you can ask the user about it and wait until you have the information.
    If the post include Google Business Profile ("gmb"), ask which of the two publication types the user wants and send it in "gmbData". A "publication" is a text update on the profile and needs text, up to 1500 characters. A "photo" adds media to the profile gallery, needs at least one image or video, and carries no text of its own — it is the only way to send a video to Google Business Profile.
    If the post is Bluesky, make sure the text does not exceed 300 characters. If the content exceeds that limit, do not retry and return an error informing the user: "Error: The text exceeds the 300-character limit allowed on Bluesky. Please edit it."
    If the post is for X (formerly Twitter), you must NOT split the message into multiple tweets or threads: it has to be scheduled as a single post. Do NOT enforce a character limit yourself, because the maximum length depends on the brand's X subscription: standard accounts are limited to 280 characters, while X Premium accounts can publish long-form posts. Schedule the post and, if the text is too long for that particular brand, this tool returns an error that you must relay to the user without modifying the text.
    The date can't be in the past.
    The response includes a `plannerUrl` for each scheduled post, pointing to it in Metricool.
    On error, the tool returns it without altering the submitted text.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `date` | string | Yes | Date and time to publish the post. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM) |
| `info` | string | Yes | Data of the post to be scheduled. Should be a json object with the following fields: autoPublish: True or False, default is True. Selects the delivery method for the scheduled post, exactly as in the Metricool web app: True publishes it automatically via the API at the scheduled time; False sends a push notification to the user's Metricool mobile app instead, so they complete the publication by hand. It does not skip validation, review, or approval steps. descendants: list with the args of the other posts if it is a thread with the format [args of the second post, args of the third post,...  ], default is empty list if there is no thread. draft: True or False, default is False. firstCommentText: Text of the first comment of the post. Default "" hasNotReadNotes: True or False, default is False. media: default is empty list. Accepts public URLs to image or video files. External sources like Google Drive or Dropbox are uploaded to Metricool automatically; for Google Drive, the user must have linked Google Drive in their Metricool account. videoThumbnailUrl: default none. Public URL of a custom jpg, jpeg or png cover image for a video post — no other image format is supported. Accepts the same external sources as media (Google Drive/Dropbox auto-uploaded). Requires a video in media, and applies only when the post includes: Instagram Reel/Trial Reel, TikTok (Business-connected accounts only — silently ignored on personal TikTok accounts), YouTube video or Short (the thumbnail only shows if the channel is verified and YouTube has enabled Shorts thumbnails on that account), LinkedIn, or Facebook Post/Reel (not Story). Outside the TikTok-personal-account case, if these conditions are not met the entire request is rejected with a VIDEO_THUMBNAIL_NOT_APPLICABLE error — omit both fields rather than sending them speculatively. videoCoverMilliseconds: default none. Alternative to videoThumbnailUrl — offset in milliseconds into the video to use as the cover frame instead of a custom image. Same requirements and network applicability as videoThumbnailUrl. mediaAltText: default is empty list. providers: always need at least one provider with the format [{"network":"<string>"}]. Use "twitter" for X posts. Use "gmb" for Google Business Profile. Valid network values are: twitter, facebook, instagram, linkedin, pinterest, youtube, tiktok, bluesky, threads, gmb. brandInfo, website, brandSummary and smartLinks are analytics-only values (used by the analytics tools) and are NOT valid providers here. publicationDate: Date and timezone of the post. The format is {dateTime:"YYYY-MM-DDTHH:mm:ss", timezone:IANA identifier}. Use the timezone of the user extracted from the getBrandSettings tool. shortener: True or False, default is False. smartLinkData: default is {ids:[]} text: Text of the post. It can be empty on Instagram (every type: the caption is optional) and on Facebook Stories; every other network in the post needs it. Stories have no caption of their own, so: a Story published automatically must not carry text when it is the only network of the post; if EVERY network of the post is a Story the text is not published anywhere, so do not send it; and when a Story is posted alongside a non-Story network the text belongs to that other network and the Story ignores it. Always you need to add the networkData for the posts, as empty if you don't have more information. Only include the networkData for the networks you have in the providers list.     The format is "twitterData": {"tags":[{"username": "string", "deleted": false}]}, Tags is used for tagging people on the images of the post, not hashtags. There could be more than one tag, following the same structure.                                 "facebookData": {"type":"<string>", "title":"<string>", "boost":<double>, "boostPayer":"<string>", "boostBeneficiary":"<string>"},                                     Facebook type can be "POST", "REEL" or "STORY"                                     Facebook title is only available for Facebook videos (This is separate from the main text of the post).                                     Facebook boost, boostPayer, and boostBeneficiary are only included if they are promoted posts.                                 "instagramData": {"type": "<string>" (default = POST), "collaborators":[{username: "string", deleted: false}]], "carouselTags": {"<media position>": [{"username": "<string>", "x": <double>, "y": <double>}]}, "showReelOnFeed": "<boolean>" (default = true), "boost":<double>, "boostPayer":"<string>", "boostBeneficiary":"<string>", "audioConfiguration": {"audioId": "<string>", "audioType": "<string>", "title": "<string>", "displayArtist": "<string>", "igUsername": "<string>", "coverArtworkUrl": "<string>", "durationMs": <integer>, "audioVolume": <integer>, "videoVolume": <integer>}, "isAiGenerated": "<boolean>" (default = false)},                                     Instagram type can be "POST", "REEL", "STORY" or "TRIAL_REEL". TRIAL_REEL is an Instagram Trial Reel (visible only to non-followers initially); it requires a video, same as REEL.                                     isAiGenerated declares that the post's content was generated or significantly altered by AI, as Instagram requires for such content. Applies to POST, REEL, TRIAL_REEL and STORY; for carousels it is a single flag for the whole post, not per image.                                     There could be more than one collaborator, following the same structure.                                     carouselTags tags people on the media (Instagram user tags, not hashtags or collaborators). Each key is the 0-based position of the item in media ("0" for a single image or a Reel) and holds the people tagged on it, so if you add, remove or reorder media, move each tag list with its media item and drop the tags of removed items. x and y place the tag on an image, from 0.0 to 1.0 measured from the top-left corner (default 0.5, the centre); Reels ignore them. Videos inside a carousel do not support people tags, so the request is rejected if you send them there; Stories only apply them on some Instagram accounts.                                     audioConfiguration only applies to REEL/TRIAL_REEL and only on Instagram Business accounts connected to a Facebook Page (otherwise the request is rejected). Only audioId is required. audioId accepts either a known numeric Instagram Audio API id, or a search term (song title/artist) that gets resolved automatically when it matches exactly one catalog result — if it matches none or several, the request is rejected with the list of candidates so you can retry with the exact numeric id. Once resolved, audioType/title/displayArtist/igUsername/coverArtworkUrl/durationMs are filled in automatically from the catalog — do not guess them, anything you send for those fields is discarded and overwritten. audioVolume and videoVolume (0-100, default 100) are the only fields under your control; omit them to keep the account's default.                                 "linkedinData": {"documentTitle": "<string>", "publishImagesAsPDF": "<boolean>" (default = false), "previewIncluded": "<boolean>" (default = true), "type": "<string>" (default = post), "poll": {"question": "<string>", "options": [{"text": "<string>"}, {"text": "<string>"}], "settings": {"duration": "<string>"}}},                                     Linkedin type can be "post" or "poll".                                     Linkedin documentTitle is the title shown for a document post (a single pdf, ppt, pptx, doc or docx document in media, or images published as a PDF carousel). Setting it does not imply publishImagesAsPDF.                                     Linkedin publishImagesAsPDF converts several images into a single PDF carousel. Only set it to true when the user explicitly asks to publish images as a PDF/document carousel; never set it when the media is a document (pdf, ppt, pptx, doc or docx).                                     Linkedin poll duration can be "ONE_DAY", "THREE_DAYS", "SEVEN_DAYS " or "FOURTEEN_DAYS ".                                 "pinterestData": {"boardId":"<string>", "pinTitle":"<string>","pinLink":"<string>", "pinNewFormat":"<boolean>", "isAiGenerated": "<boolean>" (optional field), "isAiGeneratedPerson": "<boolean>" (optional field)},                                     Pinterest boardId must be the numeric Pinterest board ID as a string (e.g. "1234567890"). NEVER pass a URL-encoded board name.                                     If you only know the board name, pass the exact human-readable name (e.g. "Baking Ideas") and it will be resolved automatically when unambiguous.                                     isAiGenerated declares that the Pin was created or significantly altered with AI, as Pinterest allows for such content. isAiGeneratedPerson declares that the Pin includes an AI-generated person and requires isAiGenerated to be true. Both apply to image and video Pins. To remove the AI declaration, set both isAiGenerated and isAiGeneratedPerson to false. When updating a post, keep the values returned by getScheduledPosts.                                 "youtubeData": {"title": "<string>", "type": "<string>" (default = video), "privacy": "<string>" (default = public), "tags": [ "<string>", "<string>" ], "category": "<string>" (optional field), "madeForKids": "<boolean>", "isAiGeneratedContent": "<boolean>" (default = false), "notifySubscribers": "<boolean>" (optional field)},                                     Youtube type can be "video" or "short" and privacy can be "public", "unlisted" or "private".                                     isAiGeneratedContent declares that the video contains realistic altered or synthetic (AI-generated) content, as YouTube requires the channel owner to declare. Applies to both "video" and "short" types.                                     notifySubscribers controls whether YouTube notifies the channel's subscribers about the upload. Omit it unless the user explicitly asks to notify or not to notify subscribers; when omitted, subscribers are notified. When updating a post, keep the value returned by getScheduledPosts. Applies to both "video" and "short" types.                                     Youtube category can be FILM_ANIMATION, AUTOS_VEHICLES, MUSIC, PETS_ANIMALS, SPORTS, TRAVEL_EVENTS, GAMING, PEOPLE_BLOGS, COMEDY, ENTERTAINMENT, NEWS_POLITICS, HOWTO_STYLE, EDUCATION, SCIENCE_TECHNOLOGY, NONPROFITS_ACTIVISM.                                 "tiktokData": {"disableComment": "<boolean>" (default = false), "disableDuet": "<boolean>" (default = false), "disableStitch": "<boolean>" (default = false), "privacyOption": "<string>" (default = "PUBLIC_TO_EVERYONE"), "commercialContentThirdParty": "<boolean>" (default = false), "commercialContentOwnBrand": "<boolean>" (default = false), "title": "<string>", "autoAddMusic": "<boolean>" (default = false), "photoCoverIndex": "<integer>" (default = 0), "isAigc": "<boolean>" (default = false)},                                     Tiktok privacyOption can be "PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "FOLLOWER_OF_CREATOR" or "SELF_ONLY".                                     isAigc declares that the video was generated or significantly edited by AI. Only applies to TikTok posts with video — TikTok does not support this declaration on photo-only posts, so it is silently ignored (not sent) when the post has no video, regardless of the value you set.                                 "blueskyData": {"postLanguages":["",""]},                                 "threadsData":{"allowedCountryCodes:["",""]},                                 "gmbData": {"type": "<string>" (default = publication)}                                     Google Business Profile type can be "publication" or "photo".                                     "publication" is a text update published on the profile: text is required, up to 1500 characters. To publish a video, use a "photo" post instead.                                     "photo" adds media to the profile gallery: at least one image or video is required, and it carries no text of its own.             The other fields are optional, but you need to add the ones you have. If you don't have more information, you can ask the user about it and wait until you have the information.  |
| `blogId` | string | Yes | Blog id of the Metricool brand account. |
| `mediaFiles` | array | No | Optional. Files attached by ChatGPT's file picker. Each entry's download_url is appended to the post's media array before scheduling. Ignored by non-ChatGPT clients. |

### Create scheduled post for review

**Slug:** `METRICOOL_MCP_CREATE_SCHEDULED_POST_FOR_REVIEW`

    Schedule a NEW post and send it to review (approval flow) in Metricool, replicating the web "Send for review".
    Use this instead of createScheduledPost ONLY when the user wants a brand-new post reviewed/approved before publishing.
    To send an ALREADY scheduled post to review, use sendScheduledPostForReview instead.
    The post content ('info') follows the SAME structure as createScheduledPost.
    Reviewers are a comma-separated list of emails. Emails of a Metricool collaborator of the brand become internal reviewers; unknown emails become external (always emailed).
    approvalSystem: "any" (one approval is enough), "all" (everyone must approve) or "optional" (auto-approve if no one rejects). A single rejection always stops publication.
    notify (default true) controls whether internal Metricool reviewers get an email; external reviewers always get one.
    Requires a plan with team management; if the plan does not allow it, this tool returns an error you must relay without retrying.
    The date can't be in the past. The response includes a `plannerUrl` pointing at the post in Metricool.
    On error, the tool returns it without altering the submitted text.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `date` | string | Yes | Date and time to publish the post once approved. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM) |
| `info` | string | Yes | Data of the post to be scheduled. Same JSON structure as createScheduledPost. |
| `blogId` | string | Yes | Blog id of the Metricool brand account. |
| `notify` | boolean | No | Notify internal Metricool reviewers by email. Default true. External reviewers are always emailed. |
| `reviewers` | string | Yes | Comma-separated list of reviewer emails, e.g. "alice@acme.com, bob@ext.com". |
| `approvalSystem` | string | Yes | Approval system: "any", "all" or "optional". |

### Get analytics available metrics

**Slug:** `METRICOOL_MCP_GET_ANALYTICS_AVAILABLE_METRICS`

Retrieves the list of available metrics for a specific social network and connector. If any metric is deprecated, the tool notifies the user and provides suggested alternatives.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `network` | string | No | The network can take the following values: bluesky, googleBusinessProfile, metaAds, googleAds, threads, facebookAds, facebook, instagram, linkedin, pinterest, tiktok, tiktokAds, twitter, twitch, youtube, brandInfo, website, brandSummary, smartLinks |
| `connector` | string | No | The connector can take the following values: evolution, posts, reels, stories, competitors, hashtags, campaigns, campaigns, age, gender, country, demographic, demographic, demographic, age and gender, videos published in range, all videos, traffic source, info, competitor posts, competitor reels, competitor videos, videos, keyworks, sources, pages, reach distribution, photos, ads, posts & photos, promoted reels, promoted posts, timeline, buttons, images. Not every connector is valid for every network. Do not combine different connectors in the same request. If network is TikTok, the connector for videos should be posts. If network is smartLinks, the connector must be one of: timeline, buttons, images. If unsure which connectors are valid for a network, omit this parameter to get metrics for all of that network's connectors. |

### Get analytics data by metrics

**Slug:** `METRICOOL_MCP_GET_ANALYTICS_DATA_BY_METRICS`

Retrieves analytical data for a specified Metricool account over a given date range, based on a selected list of metrics. The tool processes the requested metrics and returns the corresponding analytical insights for those fields.

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `to` | string | Yes | End date of the period to get the data. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM). |
| `from` | string | Yes | Init date of the period to get the data. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM). |
| `brandId` | string | Yes | Brand id of the Metricool account to get analytics for |
| `metrics` | array | No | List of Data Studio field IDs identifying metrics, formatted as network+connector+index. Ex: IGPO01. |

### Get best time to post by network

**Slug:** `METRICOOL_MCP_GET_BEST_TIME_TO_POST_BY_NETWORK`

    Get the best time to post for a specific provider. The return is a list of hours and days with a value. The higher the value, the best time to post.
    Try to get the best for as maximum of 1 week. If you have day to publish but not hours, choose the start and end of this day.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `toDate` | string | Yes | End date of the period to get the data. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM) |
| `brandId` | string | Yes | Blog id of the Metricool brand account to get competitor analytics for |
| `fromDate` | string | Yes | Init date of the period to get the data. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM) |
| `timezone` | string | Yes | Timezone of the post. Format: IANA identifier. Use the timezone from getBrandSettings tool |
| `socialNetwork` | string | Yes | Provider of the post. The format is "twitter", "facebook", "instagram", "linkedin", "youtube", "tiktok". Only these are accepted. |

### Get brand settings

**Slug:** `METRICOOL_MCP_GET_BRAND_SETTINGS`

Get the list of brands from your Metricool account.
Only Instagram, Facebook, Twitch, YouTube, Twitter, and Bluesky support competitors.


### Get scheduled posts

**Slug:** `METRICOOL_MCP_GET_SCHEDULED_POSTS`

    Get the list of scheduled posts for a specific Metricool brand (brandId).
    Only retrieves posts that are scheduled (not yet published).
    brandId is required.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `toDate` | string | Yes | End date of the period to get the data. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM) |
| `brandId` | string | Yes | Blog id of the Metricool brand account to get competitor analytics for |
| `fromDate` | string | Yes | Init date of the period to get the data. Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS±HH:MM) |
| `timezone` | string | Yes | Timezone of the post. Format: IANA identifier. Use the timezone from getBrandSettings tool |
| `extendedRange` | boolean | No | When it's true, search date range is expanded one day after and one day before. Default value is false. |

### Send scheduled post for review

**Slug:** `METRICOOL_MCP_SEND_SCHEDULED_POST_FOR_REVIEW`

    Send an ALREADY scheduled post to review (approval flow) in Metricool. Use this when the post already exists
    (you have its id and uuid from getScheduledPosts) and the user just wants it reviewed/approved.
    Like updateScheduledPost, this changes the post's id; its uuid stays the same. The response includes the post's new id, if you need to act on this same post again later in the conversation, use that id instead of the one you started with or call getScheduledPosts to obtain the unique id.
    To create a new post AND send it to review in one step, use createScheduledPostForReview instead.
    You MUST include the full original content of the post in 'info' (same JSON structure as updateScheduledPost),
    keeping every field as returned by getScheduledPosts and changing only what the user asks for.
    Reviewers are a comma-separated list of emails. Emails of a Metricool collaborator of the brand become internal reviewers; unknown emails become external (always emailed).
    approvalSystem: "any" (one approval is enough), "all" (everyone must approve) or "optional" (auto-approve if no one rejects). A single rejection always stops publication.
    notify (default true) controls whether internal Metricool reviewers get an email; external reviewers always get one.
    Requires a plan with team management; if the plan does not allow it, this tool returns an error you must relay without retrying.
    The response includes a `plannerUrl` pointing at the post in Metricool.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | Id of the already scheduled post. Get it from getScheduledPosts. Sending it to review assigns it a new id. |
| `info` | string | Yes | Full content of the post to send to review. Same JSON structure as updateScheduledPost, using the values from getScheduledPosts. |
| `uuid` | string | Yes | Uuid of the already scheduled post. Get it from getScheduledPosts. Unlike id, uuid stays the same after sending to review. |
| `blogId` | string | Yes | Blog id of the Metricool brand account. |
| `notify` | boolean | No | Notify internal Metricool reviewers by email. Default true. External reviewers are always emailed. |
| `reviewers` | string | Yes | Comma-separated list of reviewer emails, e.g. "alice@acme.com, bob@ext.com". |
| `approvalSystem` | string | Yes | Approval system: "any", "all" or "optional". |

### Update scheduled post

**Slug:** `METRICOOL_MCP_UPDATE_SCHEDULED_POST`

Update a scheduled post in Metricool. You need the id of the post to update. Get it from the getScheduledPosts tool previous on the conversation.
Updating a post changes its id; its uuid stays the same. The response includes the post's new id, if you need to update this same post again later in the conversation, use that id instead of the one you started with or call getScheduledPosts to obtain the unique id.
Updating a scheduled post overwrites its content immediately; there is no confirmation step or undo in the API.
Errors from this endpoint are final; retrying with the same input will not change the result.
To update the post, ensure the full original content is included in the request, modifying only the new information while keeping the rest unchanged and maintaining the original structure.
Keep instagramData.carouselTags as getScheduledPosts returns it unless the user asks to change the people tags or the media: the update replaces the whole post, so leaving it out removes every people tag.
If the post include Instagram, is a must to have at least one image or video. Posts must include an image or a carousel, Reels and Trial Reels must include a video, and Stories can include either an image or a video. If you don't have more information, you can ask the user about it and wait until you have the information.
If the post include Pinterest, is a must to have a image and the board where to publish the pin. If you don't have more information, you can ask the user about it and wait until you have the information.
If the post include Youtube, is a must to have a video, select the audience (if it's video made for kids or not) and the title of the video. If you don't have more information, you can ask the user about it and wait until you have the information.
If the post include Tiktok, is a must to have at least one image or video. If you don't have more information, you can ask the user about it and wait until you have the information.
If the post is Facebook Reel, is a must to have a video. If is Facebook Story, image or video is needed. If you don't have more information, you can ask the user about it and wait until you have the information.
If the post include Google Business Profile ("gmb"), keep the "gmbData" type of the original post unless the user asks to change it. A "publication" is a text update on the profile and needs text, up to 1500 characters. A "photo" adds media to the profile gallery, needs at least one image or video, and carries no text of its own.
If the post is Bluesky, make sure the text does not exceed 300 characters. If the content exceeds that limit, do not retry and return an error informing the user: "Error: The text exceeds the 300-character limit allowed on Bluesky. Please edit it."
If the post is for X (formerly Twitter), you must NOT split the message into multiple tweets or threads: it has to be scheduled as a single post. Do NOT enforce a character limit yourself, because the maximum length depends on the brand's X subscription: standard accounts are limited to 280 characters, while X Premium accounts can publish long-form posts. Schedule the post and, if the text is too long for that particular brand, this tool returns an error that you must relay to the user without modifying the text.
The date can't be in the past.
The response includes a `plannerUrl` for each post, pointing to it in Metricool.


#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string | Yes | Id of the post to update. Get it from the getScheduledPosts tool previous on the conversation. Updating the post assigns it a new id. |
| `info` | string | Yes | Data of the post to be scheduled. Should be a json object with the following fields: autoPublish: True or False, default is True. Selects the delivery method for the scheduled post, exactly as in the Metricool web app: True publishes it automatically via the API at the scheduled time; False sends a push notification to the user's Metricool mobile app instead, so they complete the publication by hand. It does not skip validation, review, or approval steps. descendants: list with the args of the other posts if it is a thread with the format [args of the second post, args of the third post,...  ], default is empty list if there is no thread. draft: True or False, default is False. firstCommentText: Text of the first comment of the post. Default "" hasNotReadNotes: True or False, default is False. media: default is empty list. Accepts public URLs to image or video files. External sources like Google Drive or Dropbox are uploaded to Metricool automatically; for Google Drive, the user must have linked Google Drive in their Metricool account. videoThumbnailUrl: default none. Public URL of a custom jpg, jpeg or png cover image for a video post — no other image format is supported. Accepts the same external sources as media (Google Drive/Dropbox auto-uploaded). Requires a video in media, and applies only when the post includes: Instagram Reel/Trial Reel, TikTok (Business-connected accounts only — silently ignored on personal TikTok accounts), YouTube video or Short (the thumbnail only shows if the channel is verified and YouTube has enabled Shorts thumbnails on that account), LinkedIn, or Facebook Post/Reel (not Story). Outside the TikTok-personal-account case, if these conditions are not met the entire request is rejected with a VIDEO_THUMBNAIL_NOT_APPLICABLE error — omit both fields rather than sending them speculatively. videoCoverMilliseconds: default none. Alternative to videoThumbnailUrl — offset in milliseconds into the video to use as the cover frame instead of a custom image. Same requirements and network applicability as videoThumbnailUrl. mediaAltText: default is empty list. providers: always need at least one provider with the format [{"network":"<string>"}]. Use "twitter" for X posts. Use "gmb" for Google Business Profile. Valid network values are: twitter, facebook, instagram, linkedin, pinterest, youtube, tiktok, bluesky, threads, gmb. brandInfo, website, brandSummary and smartLinks are analytics-only values (used by the analytics tools) and are NOT valid providers here. publicationDate: Date and timezone of the post. The format is {dateTime:"YYYY-MM-DDTHH:mm:ss", timezone:IANA identifier}. Use the timezone of the user extracted from the getBrandSettings tool. shortener: True or False, default is False. smartLinkData: default is {ids:[]} text: Text of the post. It can be empty on Instagram (every type: the caption is optional) and on Facebook Stories; every other network in the post needs it. Stories have no caption of their own, so: a Story published automatically must not carry text when it is the only network of the post; if EVERY network of the post is a Story the text is not published anywhere, so do not send it; and when a Story is posted alongside a non-Story network the text belongs to that other network and the Story ignores it. Always you need to add the networkData for the posts, as empty if you don't have more information. Only include the networkData for the networks you have in the providers list.     The format is "twitterData": {"tags":[{"username": "string", "deleted": false}]}, Tags is used for tagging people on the images of the post, not hashtags. There could be more than one tag, following the same structure.                                 "facebookData": {"type":"<string>", "title":"<string>", "boost":<double>, "boostPayer":"<string>", "boostBeneficiary":"<string>"},                                     Facebook type can be "POST", "REEL" or "STORY"                                     Facebook title is only available for Facebook videos (This is separate from the main text of the post).                                     Facebook boost, boostPayer, and boostBeneficiary are only included if they are promoted posts.                                 "instagramData": {"type": "<string>" (default = POST), "collaborators":[{username: "string", deleted: false}]], "carouselTags": {"<media position>": [{"username": "<string>", "x": <double>, "y": <double>}]}, "showReelOnFeed": "<boolean>" (default = true), "boost":<double>, "boostPayer":"<string>", "boostBeneficiary":"<string>", "audioConfiguration": {"audioId": "<string>", "audioType": "<string>", "title": "<string>", "displayArtist": "<string>", "igUsername": "<string>", "coverArtworkUrl": "<string>", "durationMs": <integer>, "audioVolume": <integer>, "videoVolume": <integer>}, "isAiGenerated": "<boolean>" (default = false)},                                     Instagram type can be "POST", "REEL", "STORY" or "TRIAL_REEL". TRIAL_REEL is an Instagram Trial Reel (visible only to non-followers initially); it requires a video, same as REEL.                                     isAiGenerated declares that the post's content was generated or significantly altered by AI, as Instagram requires for such content. Applies to POST, REEL, TRIAL_REEL and STORY; for carousels it is a single flag for the whole post, not per image.                                     There could be more than one collaborator, following the same structure.                                     carouselTags tags people on the media (Instagram user tags, not hashtags or collaborators). Each key is the 0-based position of the item in media ("0" for a single image or a Reel) and holds the people tagged on it, so if you add, remove or reorder media, move each tag list with its media item and drop the tags of removed items. x and y place the tag on an image, from 0.0 to 1.0 measured from the top-left corner (default 0.5, the centre); Reels ignore them. Videos inside a carousel do not support people tags, so the request is rejected if you send them there; Stories only apply them on some Instagram accounts.                                     audioConfiguration only applies to REEL/TRIAL_REEL and only on Instagram Business accounts connected to a Facebook Page (otherwise the request is rejected). Only audioId is required. audioId accepts either a known numeric Instagram Audio API id, or a search term (song title/artist) that gets resolved automatically when it matches exactly one catalog result — if it matches none or several, the request is rejected with the list of candidates so you can retry with the exact numeric id. Once resolved, audioType/title/displayArtist/igUsername/coverArtworkUrl/durationMs are filled in automatically from the catalog — do not guess them, anything you send for those fields is discarded and overwritten. audioVolume and videoVolume (0-100, default 100) are the only fields under your control; omit them to keep the account's default.                                 "linkedinData": {"documentTitle": "<string>", "publishImagesAsPDF": "<boolean>" (default = false), "previewIncluded": "<boolean>" (default = true), "type": "<string>" (default = post), "poll": {"question": "<string>", "options": [{"text": "<string>"}, {"text": "<string>"}], "settings": {"duration": "<string>"}}},                                     Linkedin type can be "post" or "poll".                                     Linkedin documentTitle is the title shown for a document post (a single pdf, ppt, pptx, doc or docx document in media, or images published as a PDF carousel). Setting it does not imply publishImagesAsPDF.                                     Linkedin publishImagesAsPDF converts several images into a single PDF carousel. When updating a post, keep the publishImagesAsPDF value returned by getScheduledPosts unless the user explicitly asks to change it; never set it when the media is a document (pdf, ppt, pptx, doc or docx).                                     Linkedin poll duration can be "ONE_DAY", "THREE_DAYS", "SEVEN_DAYS " or "FOURTEEN_DAYS ".                                 "pinterestData": {"boardId":"<string>", "pinTitle":"<string>","pinLink":"<string>", "pinNewFormat":"<boolean>", "isAiGenerated": "<boolean>" (optional field), "isAiGeneratedPerson": "<boolean>" (optional field)},                                     Pinterest boardId must be the numeric Pinterest board ID as a string (e.g. "1234567890"). NEVER pass a URL-encoded board name.                                     If you only know the board name, pass the exact human-readable name (e.g. "Baking Ideas") and it will be resolved automatically when unambiguous.                                     isAiGenerated declares that the Pin was created or significantly altered with AI, as Pinterest allows for such content. isAiGeneratedPerson declares that the Pin includes an AI-generated person and requires isAiGenerated to be true. Both apply to image and video Pins. To remove the AI declaration, set both isAiGenerated and isAiGeneratedPerson to false. When updating a post, keep the values returned by getScheduledPosts.                                 "youtubeData": {"title": "<string>", "type": "<string>" (default = video), "privacy": "<string>" (default = public), "tags": [ "<string>", "<string>" ], "category": "<string>" (optional field), "madeForKids": "<boolean>", "isAiGeneratedContent": "<boolean>" (default = false), "notifySubscribers": "<boolean>" (optional field)},                                     Youtube type can be "video" or "short" and privacy can be "public", "unlisted" or "private".                                     isAiGeneratedContent declares that the video contains realistic altered or synthetic (AI-generated) content, as YouTube requires the channel owner to declare. Applies to both "video" and "short" types.                                     notifySubscribers controls whether YouTube notifies the channel's subscribers about the upload. Omit it unless the user explicitly asks to notify or not to notify subscribers; when omitted, subscribers are notified. When updating a post, keep the value returned by getScheduledPosts. Applies to both "video" and "short" types.                                     Youtube category can be FILM_ANIMATION, AUTOS_VEHICLES, MUSIC, PETS_ANIMALS, SPORTS, TRAVEL_EVENTS, GAMING, PEOPLE_BLOGS, COMEDY, ENTERTAINMENT, NEWS_POLITICS, HOWTO_STYLE, EDUCATION, SCIENCE_TECHNOLOGY, NONPROFITS_ACTIVISM.                                 "tiktokData": {"disableComment": "<boolean>" (default = false), "disableDuet": "<boolean>" (default = false), "disableStitch": "<boolean>" (default = false), "privacyOption": "<string>" (default = "PUBLIC_TO_EVERYONE"), "commercialContentThirdParty": "<boolean>" (default = false), "commercialContentOwnBrand": "<boolean>" (default = false), "title": "<string>", "autoAddMusic": "<boolean>" (default = false), "photoCoverIndex": "<integer>" (default = 0), "isAigc": "<boolean>" (default = false)},                                     Tiktok privacyOption can be "PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "FOLLOWER_OF_CREATOR" or "SELF_ONLY".                                     isAigc declares that the video was generated or significantly edited by AI. Only applies to TikTok posts with video — TikTok does not support this declaration on photo-only posts, so it is silently ignored (not sent) when the post has no video, regardless of the value you set.                                 "blueskyData": {"postLanguages":["",""]},                                 "threadsData":{"allowedCountryCodes:["",""]},                                 "gmbData": {"type": "<string>" (default = publication)}                                     Google Business Profile type can be "publication" or "photo".                                     "publication" is a text update published on the profile: text is required, up to 1500 characters. To publish a video, use a "photo" post instead.                                     "photo" adds media to the profile gallery: at least one image or video is required, and it carries no text of its own.             The other fields are optional, but you need to add the ones you have. If you don't have more information, you can ask the user about it and wait until you have the information.  |
| `uuid` | string | Yes | Uuid of the post to update. Get it from the getScheduledPosts tool previous on the conversation. Unlike id, uuid stays the same across updates. |
| `blogId` | string | Yes | Blog id of the Metricool brand account. |
| `mediaFiles` | array | No | Optional. Files attached by ChatGPT's file picker. Each entry's download_url is appended to the post's media array before scheduling. Ignored by non-ChatGPT clients. |
