أدوات Meta: صفحات Facebook و Instagram
في هذه الصفحة 36 أداة. هذه الصفحة مولَّدة آليًا من قائمة الأدوات في الخادم نفسه، الإصدار 0.1.0، ولا تُحرَّر باليد. أوصاف الأدوات مكتوبة للمساعد الذكي، وهي بالإنجليزية ولم تُترجم، فكل ما تحت هذه الفقرة بالإنجليزية كما يقرؤه المساعد الذكي. لا تحتاج إلى معرفة اسم أي أداة لتطلب عملًا: هذه الصفحة مرجع لمن يريد أن يعرف ما تأخذه كل أداة بالضبط. صفحة كل الأدوات تسرد الصفحات كلها.
meta_list_media
Kind: read. It is marked as changing nothing.
Your own uploaded images and videos, newest first, with the media_id each posting tool takes. Files arrive through meta_add_media, or a person uploads them on the Media page of the management site. Find the file the user means by its name, then pass its media_id.
It takes no arguments.
meta_add_media
Kind: write.
Add an image or video to your media library, and get the media_id the posting tools take.
Give one source:
- url: a public https URL. This server downloads it; nothing is posted.
- path: a file on this server, inside one of the media folders an administrator has named (server_status lists them) - a full path, or one relative to a folder. Anything outside those folders is refused, so a file the user has elsewhere has to be moved into one, or uploaded on the Media page instead.
Only JPEG and PNG images, MP4 or MOV videos and PDF documents are kept, judged by the file's contents. The library is shared with LinkedIn: a PDF is for linkedin_post only.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
url | text | no | none | Public https URL of the file. |
path | text | no | none | A file inside one of the server's media folders. |
filename | text | no | none | Optional name to show in the library. Defaults to the file's own. |
meta_create_upload_link
Kind: write.
Get a one-time URL to send a file on YOUR machine into the user's media library.
Use this when the file is on the machine you run commands on and is not at a public URL: MCP cannot carry a file's bytes, but you can send them with one command. Works only if you can run a shell command; otherwise ask the user to upload on the Media page.
How to send the file:
- Method PUT (POST also works) to upload_url.
- The request body is the raw file bytes and nothing else: not a form, not multipart, not base64, not JSON.
- Optional header X-Filename: the name to show in the library (URL-encode anything that is not plain ASCII). Without it, the filename given here is used.
- No Authorization header: the URL itself is the permission.
curl: curl -T "/path/to/photo.jpg" "<upload_url>"PowerShell: Invoke-RestMethod -Method Put -InFile "C:\path\photo.jpg" -Uri "<upload_url>" - The reply is JSON with media_id. Pass that to meta_post_to_facebook or meta_post_to_instagram, or linkedin_post. Nothing is posted by the upload itself.
Limits: one file, JPEG or PNG image, MP4 or MOV video or PDF (judged by content), up to max_bytes, within 15 minutes. The link works once - even a failed attempt uses it up, so create a new one to try again. Never show the URL to anyone else.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
filename | text | no | none | The name to show in the library, e.g. "launch.jpg". |
meta_list_accounts
Kind: read. It is marked as changing nothing.
List the Facebook Pages your Meta login administers, and the Instagram Business accounts linked to them. Start here: every other meta_* tool needs one of these ids.
It takes no arguments.
meta_list_posts
Kind: read. It is marked as changing nothing.
Posts on a Facebook Page or an Instagram account, newest first: the most recent, or the ones in a range of dates, a page at a time.
On a Page this includes drafts and scheduled posts, each marked with its state ("live", "draft" or "scheduled"). That is how you find the id of a post that is not live yet: meta_publish_draft publishes a draft or a scheduled post now, meta_update_scheduled_post moves or rewrites a scheduled one, and meta_cancel_draft discards either. Drafts and scheduled posts come with the first page only, and not at all when since or until is given: a range is of posts that are live.
When the answer has next_after there are more: call again with the same arguments and after set to it.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | no | none | Facebook Page id from meta_list_accounts. |
ig_account_id | text | no | none | Instagram Business account id from meta_list_accounts. Give one or the other. |
limit | whole number | no | 25 | How many to return in one page (1-100). On a Page's first page this caps the merged list, so a burst of drafts can push older live posts past it. |
include_unpublished | true or false | no | true | Facebook only. false returns only posts that are already live. |
since | text | no | none | Only posts made at or after this time: a date (2026-09-01, read as UTC) or an ISO 8601 date-time. |
until | text | no | none | Only posts made up to this time, in the same form. A bare date is the start of that day, so to include a day give the one after it. |
after | text | no | none | next_after from the last answer, for the page that follows it. |
meta_post_insights
Kind: read. It is marked as changing nothing.
How one Facebook Page post performed. For every post of a period use meta_content_report instead: it is one call, not one per post.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page the post belongs to, which is what authorises the read. | |
post_id | text | yes | Post id from meta_list_posts, e.g. "123456789_987654321". | |
metrics | text | no | none | Comma-separated metric names from this server's list. Defaults to views, unique views, clicks and reactions. A name Meta has removed is refused with the one that replaced it. With video_id, a video metric may be named here too. |
video_id | text | no | none | For a video or a reel, its video id (meta_content_report gives it): the video's own figures are read as well - plays and replays for a reel, watch time, the retention graph. Meta keeps these on the video, not on the post. |
meta_instagram_insights
Kind: read. It is marked as changing nothing.
How one Instagram post performed. For every post of a period use meta_content_report instead: it is one call, not one per post.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | The Instagram Business account the media belongs to. | |
media_id | text | yes | Media id from meta_list_posts. | |
metrics | text | no | none | Comma-separated metric names from this server's list. Left out, the media is read first and its own kind's metrics are asked for: a feed post's (reach, likes, comments, saves, shares, interactions, views), a reel's (the same and its watch time, which Meta gives in milliseconds) or a story's. A name Meta has removed is refused with the one that replaced it. |
meta_publishing_limit
Kind: read. It is marked as changing nothing.
What is left of the posting quotas, both Meta's and this server's.
Meta allows 100 API-published Instagram posts per rolling 24 hours. This server applies its own, lower, limit on top - set by an administrator and counted from the audit log. A scheduled Facebook post counts on the day it goes out, not the day it was scheduled, so scheduled_ahead is not part of what is used. Replies to comments have a separate cap of their own, reported beside it.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Instagram Business account id from meta_list_accounts. |
meta_content_report
Kind: read. It is marked as changing nothing.
Every post of a Facebook Page, an Instagram account, or both, in a range of dates, each with its figures, then totals and averages per type. Use this for a period's posts - a monthly report, the best post of a quarter - rather than meta_list_posts and a call per post: it costs a handful of Graph calls however many posts there are.
Each post has platform, id, date (UTC), type (image, carousel, reel, video, story, text, link), the start of its caption, its permalink and metrics: views, reach and interactions on both platforms, with clicks and reactions on Facebook and likes and saves on Instagram. On Facebook reach is the people who saw the post (Meta retired the older figure) and interactions is reactions, comments and shares added up here. A reel on Instagram also has avg_watch_seconds and total_watch_seconds. A Facebook video or reel carries video_id: meta_post_insights with it reads the video's own figures. metrics is null where Meta gave none; the warnings say why.
The summary is per platform and type, over the posts listed. Reach is averaged, never added up: one person reached by two posts would be counted twice.
An Instagram story is listed only while it is live (24 hours): once it has expired Meta no longer has it. For the stories of a past period use meta_story_report, which has what this server kept of a watched account's stories (history_watch). Figures for the last two days may still be rising.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
since | text | yes | Start of the range: a date (2026-09-01, read as UTC) or an ISO 8601 date-time. | |
until | text | yes | End of the range, in the same form. A bare date is the start of that day, so for all of September give 2026-10-01. At most 93 days after since. | |
page_id | text | no | none | Facebook Page id from meta_list_accounts. |
ig_account_id | text | no | none | Instagram Business account id from meta_list_accounts. Give either or both. |
media_types | text | no | none | Comma-separated types to keep, from the list above. Default: all. |
sort_by | text | no | "date" | date (newest first, the default), reach, views or interactions. |
limit | whole number | no | 100 | The most posts to read per account (1-200). Types are filtered after reading, so fewer may be listed. |
after | text | no | none | next_after from the last answer, with the same other arguments, for the posts that follow. The summary of each answer covers that answer's posts only. |
meta_list_stories
Kind: read. It is marked as changing nothing.
The stories an Instagram account has up right now, each with its figures so far: views, reach, replies, shares, follows, profile visits, link clicks, interactions, and navigation (taps forward and back, exits, swipes to the next story).
A story lives 24 hours and Meta then drops its figures for good. This reads them now and keeps nothing. To have them kept, the account has to be watched (history_watch): then this server reads each story before it expires, and meta_story_report gives the stories of a past period. watched says whether you are watching this account; if not, offer to.
Each story costs two calls to Meta, so figures are read for the 10 newest. A story with under five viewers has no figures: Meta answers it with an error, given as note.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Instagram Business account id from meta_list_accounts. |
meta_story_report
Kind: read. It is marked as changing nothing.
The Instagram stories of a past period, from what this server kept: one row per story with the last figures read before it expired, and totals.
Meta drops a story's figures 24 hours after it was posted, so this is not read from Meta. It exists only for an account you had this server watch (history_watch, platform meta, kind instagram_stories) and only from the day the watching began. A story that was posted and expired while the server was not running, or before the account was watched, was never seen and is not here: watched_since and unread_periods say where that may be so. Say that to the user rather than presenting the list as complete.
Each story has captured_after_hours: how long after posting its figures were last read. Under 20 the server did not see its last hours (it was stopped), so the true figures are higher; read_early counts those. A story with under five viewers has no figures. Reach is averaged, never added up: one person may have seen several stories.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Instagram Business account id from meta_list_accounts. | |
since | text | yes | Start of the range: a date (2026-09-01, read as UTC) or an ISO 8601 date-time. | |
until | text | yes | End of the range, in the same form. A bare date is the start of that day, so for all of September give 2026-10-01. |
meta_page_insights
Kind: read. It is marked as changing nothing.
A Facebook Page's own figures over a range of dates: followers, follows and unfollows, views, the people who saw its content, Page visits, engagements, video views. For the posts of a period use meta_content_report; this is the Page as a whole.
Each metric comes as a series, one value per day with the time Meta ends that day (end), and with period=day a total over the range. Two are never added up: page_follows is the running number of followers (the answer gives the latest as followers), and page_total_media_view_unique counts people, who may be there on several days. followers_gained is follows minus unfollows, worked out here.
Meta answers 90 days at a time, so a longer range is read in windows, at most 5 (450 days); a wider one is refused. Meta keeps about two years. Days older than that are answered from what this server kept, if the Page was watched then (history_watch, kind facebook_page): daily figures only, each point marked source stored or live, and followers by country or city as they stood. For kept figures alone, with weeks, months and a comparison, use history_report.
Meta removed page_impressions, page_fans and the like: such a name is refused with the one that replaced it. It also removed followers by age and gender, and named nothing in their place.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | Facebook Page id from meta_list_accounts. | |
since | text | yes | Start of the range: a date (2026-09-01, read as UTC) or an ISO 8601 date-time. | |
until | text | yes | End of the range, in the same form. A bare date is the start of that day, so for all of September give 2026-10-01. | |
metrics | text | no | none | Comma-separated names. Default: page_follows, page_daily_follows_unique, page_daily_unfollows_unique, page_media_view, page_total_media_view_unique, page_views_total, page_post_engagements, page_video_views, page_total_actions, page_actions_post_reactions_total. Also: page_daily_follows, page_video_view_time, page_actions_post_reactions_like_total (and love, wow, haha, sorry, anger). |
period | text | no | "day" | day (the default), week or days_28: the last two are a rolling window ending on each day, so they are not added up. Some metrics take day only. |
breakdown | text | no | none | country or city: the Page's followers by place as of the end of the range, and nothing else (give no metrics). is_from_ads or is_from_followers: page_media_view split that way. |
meta_instagram_account_insights
Kind: read. It is marked as changing nothing.
An Instagram account's own figures: followers now, and over a range of dates reach, views, accounts engaged, interactions, follows and unfollows; who the followers are; when they are online. For the posts of a period use meta_content_report.
Give since and until for the figures of a range, demographics for who the followers are, best_times for when they are online, or any of them together.
Over a range each metric is one figure per window. Meta answers 30 days at a time, so a longer range is read in windows, at most 13 (390 days); a wider one is refused. total adds the windows up, except for reach and accounts_engaged: they count people, and one person may be in several windows, so they are given per window only - never add them up. followers_gained is follows minus unfollows, worked out here.
Demographics are NOT of a range of dates: Meta gives them for a recent window it names (timeframe), and they have no past. since and until do not apply to them. The one past they have is this server's own: for an account it was asked to watch (history_watch, kind instagram_account) it keeps the followers' demographics weekly, and as_of reads the newest kept on or before a date, marked source stored.
Where Meta sends nothing for a metric in the range, the days this server kept of it are given in its place, under stored.
Figures for the last two days may be incomplete: Meta's data can trail by 48 hours.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Instagram Business account id from meta_list_accounts. | |
since | text | no | none | Start of the range: a date (2026-09-01, read as UTC) or an ISO 8601 date-time. |
until | text | no | none | End of the range, in the same form. A bare date is the start of that day. |
metrics | text | no | none | Comma-separated, from: reach, views, accounts_engaged, total_interactions, likes, comments, saves, shares, replies, reposts, profile_links_taps, follows_and_unfollows. Default: all of them. |
breakdown | text | no | none | Split the figures: media_product_type (reach, views, total_interactions, likes, comments, saves, shares), follow_type (reach, follows_and_unfollows), follower_type (views) or contact_button_type (profile_links_taps). With no metrics given, the ones that take it are read. |
demographics | text | no | none | followers or engaged (the accounts that engaged), split by by. |
by | text | no | none | age, gender, country or city. Needed with demographics. |
timeframe | text | no | "last_30_days" | The window of the demographics: this_week, this_month, last_14_days, last_30_days (the default), last_90_days or prev_month. |
best_times | true or false | no | false | true for the followers online in each hour of the day, over the last 30 days. Meta gives it only for an account with 100 followers or more. |
as_of | text | no | none | With demographics=followers: a date, to read what this server kept on or before it instead of asking Meta. Only for a watched account. |
meta_list_comments
Kind: read. It is marked as changing nothing.
The comments on one Facebook Page post or Instagram post, newest first, replies included. For a regular moderation pass use meta_list_new_comments instead.
Every comment has the same shape on both platforms: comment_id, text, author, created_time (UTC), hidden, parent_id (set on a reply), reply_count, can_hide and can_reply. author is often null on Facebook: Meta withholds who wrote a comment unless that person authorised the app.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
post_id | text | yes | Post id (Facebook) or media id (Instagram) from meta_list_posts. | |
page_id | text | no | none | The Facebook Page the post is on. |
ig_account_id | text | no | none | The Instagram Business account the media is on. Give one or the other. |
limit | whole number | no | 50 | How many to return (1-200). |
include_hidden | true or false | no | true | false leaves out comments that have been hidden. Instagram never returns a hidden comment at all; to unhide one, take its id from get_audit_log. |
meta_list_new_comments
Kind: read. It is marked as changing nothing.
Comments that arrived since you last marked them seen, across the most recent posts of a Facebook Page or an Instagram account. Oldest first within each post.
An ad's post is often on no timeline, so it is not among the recent posts. Give ad_account_id to add the posts of this Page or Instagram account that are running as ads from that ad account; each post then says is_ad, and an ad's post lists its ads.
Reading marks nothing seen. Deal with the comments first, then pass the returned cursor to meta_mark_comments_seen, so a pass that stops halfway loses nothing. On a post never marked before, every comment is new.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | no | none | Facebook Page id from meta_list_accounts. |
ig_account_id | text | no | none | Instagram Business account id. Give one or the other. |
posts | whole number | no | 10 | How many of the most recent posts to look at (1-25). |
ad_account_id | text | no | none | From meta_ads_list_accounts: also look at the posts its running ads show (up to 25 more). Needs Meta Ads switched on. |
meta_mark_comments_seen
Kind: write.
Mark the comments a meta_list_new_comments call returned as dealt with, so the next call only returns what arrives after them. Changes nothing on Facebook or Instagram - only this server's note of how far you have read - and never moves that note backwards. Needs no write access.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
cursor | text | yes | The cursor meta_list_new_comments returned, unchanged. |
meta_inbox_list
Kind: read. It is marked as changing nothing.
The private conversations of a Page (platform=messenger) or of the Instagram account linked to it (platform=instagram), newest first: who each is with, when the last message was, whether the last word is theirs (unanswered), and whether Meta's 24-hour messaging window is still open - a Page may reply only for 24 hours after the person last wrote. No message text is read here; meta_inbox_read shows a conversation.
Messages are people's private words: this server stores none of them. It answers only while an administrator has switched messages on, and the Meta connection must have been granted the messaging permissions.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page, from meta_list_accounts. For Instagram too: its messages are reached through the Page the account is linked to. | |
platform | one of messenger, instagram | yes | messenger or instagram. | |
unanswered_only | true or false | no | true | true (default) = only conversations whose last message is the person's. |
limit | whole number | no | 25 | How many conversations to read, 1 to 50. |
after | text | no | none | The "more" cursor of a previous answer, for the next page. |
meta_inbox_read
Kind: read. It is marked as changing nothing.
The recent messages of one conversation, oldest first, each marked as from them or from us, with whether the 24-hour messaging window is open. Meta gives the 20 newest messages of a conversation and no more. A message with no text is an attachment, a sticker, a reaction or a reply to a story, which are not read here.
What comes back is a person's private words, and often their contact details: show it to the user who asked and use it for the reply, and do not copy it anywhere else. This server stores none of it.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page, from meta_list_accounts (for Instagram, the Page the account is linked to). | |
platform | one of messenger, instagram | yes | messenger or instagram, as given to meta_inbox_list. | |
conversation_id | text | yes | From meta_inbox_list. | |
limit | whole number | no | 20 | How many of the newest messages, 1 to 20. |
meta_list_mentions
Kind: read. It is marked as changing nothing.
Where the business is tagged: the Instagram posts that tag the account (ig_account_id) and the public Facebook posts that tag the Page (page_id), newest first, each with who posted it where Meta says, its text, its link and, on Instagram, its likes and comments. Give either id or both.
Tags only. An @mention in a caption or a comment is NOT included and cannot be: Meta gives an app such a mention only as an id sent to a webhook, and has no list of them. Do not tell the user nobody mentioned them because this list is empty.
The Instagram half needs the instagram_manage_comments permission, which a connection holds only where an administrator has switched comments on. These are other people's posts: nothing of them is stored.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | no | none | A Page, from meta_list_accounts, for the Facebook posts that tag it. |
ig_account_id | text | no | none | An Instagram account, from meta_list_accounts, for the posts it is tagged in. |
limit | whole number | no | 25 | How many of each, 1 to 50. |
after | text | no | none | A cursor from a previous answer's "more", with the one id it belongs to. |
meta_hashtag_search
Kind: read. It is marked as changing nothing.
Public Instagram posts under one hashtag: the most popular (kind=top) or those of the last 24 hours (kind=recent), each with its text, link, likes and comments. Meta names no author.
Meta allows an Instagram account 30 DIFFERENT hashtags in a rolling 7 days. This server counts them: the answer's budget says how many are left, a hashtag already looked up this week is free to search again, and the thirty-first is refused before Meta is asked, with when a slot frees. So choose hashtags with the user rather than trying many.
Works only where an administrator has switched hashtag search on, which they do once the Meta app has the Instagram Public Content Access feature. Nothing found is stored; the activity log keeps the hashtag looked up, its id and the time.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | The Instagram account to search as, from meta_list_accounts. | |
hashtag | text | yes | One hashtag, with or without the #. No spaces, no emoji. | |
kind | one of top, recent | no | "top" | top (default) or recent (the last 24 hours). |
limit | whole number | no | 25 | How many posts, 1 to 50. |
meta_competitor_snapshot
Kind: read. It is marked as changing nothing.
Another Instagram account's public figures, in one call: followers, how many posts it has, and for its newest posts the likes, comments and views, with averages. Only a public Business or Creator account can be read; any other is "not available", as Meta answers.
These are the figures anyone sees in the app. Meta gives no insights for an account that is not yours - no reach, saves, shares or demographics - so do not present any. The engagement rate in the answer is this server's own rule of thumb, stated with its sum: say so when you quote it, and never call it Meta's figure. Nothing is stored.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Your own Instagram account to ask as, from meta_list_accounts. | |
username | text | yes | The other account's username, with or without the @. | |
media_limit | whole number | no | 12 | How many of its newest posts to read, 1 to 25. |
meta_post_to_facebook
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Post to a Facebook Page: text, optionally with a link, one image, several images or one video.
The call decides what happens to the post. By default it is created as a draft: not live, and waiting for meta_publish_draft. publish_now=true puts it live at once. schedule_at hands it to Facebook to publish at that time. Note that dry_run here is this server's own preflight, not a Meta-side validation: Meta has no validate-only mode.
Give at most one media source; for several photos in one post that source is images. For a file the user has, they upload it on the Media page of the management site; find it with meta_list_media and pass its media_id.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | Facebook Page id from meta_list_accounts. | |
message | text | yes | The post text (the video description, for a video). | |
link | text | no | none | A URL to attach. Only for a text post. |
image_url | text | no | none | Public https URL of a JPEG or PNG to post as a photo. |
video_url | text | no | none | Public https URL of an MP4 to post as a video. Meta fetches it. |
media_id | text | no | none | An image or video from the caller's library (meta_list_media). |
media_path | text | no | none | A file inside one of the server's media folders - a full path, or one relative to a folder. Only when an administrator has named folders (see server_status); otherwise use media_id, or meta_add_media first. |
images | list of text | no | none | Several photos in one post: 2 to 10 entries in the order they should appear, each a public https URL or a library media_id. Not with any other media or a link. |
title | text | no | none | Optional title, for a video. |
schedule_at | text | no | none | Publish at this time instead, ISO 8601 (e.g. 2026-10-01T09:30:00+02:00) or a Unix timestamp. Facebook accepts 10 minutes to 30 days ahead. |
publish_now | true or false | no | false | true = live as soon as it is sent. false (default) = a draft, unless schedule_at is given. Cannot be combined with schedule_at. |
dry_run | true or false | no | true | true = preflight only (default). false = actually send it, after the user confirms. |
meta_post_reel_to_facebook
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Post a reel to a Facebook Page: a short vertical video, through Facebook's Reels publishing rather than as an ordinary Page video.
Like every posting tool, it makes a draft by default, publish_now=true puts it live at once, and schedule_at hands it to Facebook to publish at that time. A draft or scheduled reel is known by its video id: pass that to meta_publish_draft, meta_update_scheduled_post or meta_cancel_draft. dry_run is this server's own preflight, not a Meta-side validation.
A reel is 3 to 90 seconds, 9:16, at least 540x960. A file from the library or a media folder is measured and checked in the dry run; a video at a URL is not inspected.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | Facebook Page id from meta_list_accounts. | |
description | text | yes | The reel's text. | |
video_url | text | no | none | Public https URL of an MP4. Meta fetches it. |
media_id | text | no | none | A video from the caller's library (meta_list_media). |
media_path | text | no | none | A video inside one of the server's media folders, when an administrator has named folders (see server_status). |
title | text | no | none | Optional title. |
schedule_at | text | no | none | Publish at this time instead, ISO 8601 or a Unix timestamp, at least 10 minutes ahead. Cannot be combined with publish_now. |
publish_now | true or false | no | false | true = live as soon as it is processed. false (default) = a draft, unless schedule_at is given. |
dry_run | true or false | no | true | true = preflight only (default). false = actually send it, after the user confirms. |
meta_post_story_to_facebook
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Post a story to a Facebook Page: one photo or one video.
A story has no draft and no schedule: Facebook offers neither. So this is the one posting tool where dry_run=false publishes at once - there is no publish_now to ask for, and nothing to publish later. A story disappears by itself after 24 hours and cannot be withdrawn from here before that. Confirm with the user before dry_run=false.
A story video is 3 to 90 seconds, 9:16, at least 540x960. A file from the library or a media folder is measured and checked in the dry run; one at a URL is not inspected.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | Facebook Page id from meta_list_accounts. | |
image_url | text | no | none | Public https URL of a photo. |
video_url | text | no | none | Public https URL of an MP4. Meta fetches it. |
media_id | text | no | none | An image or video from the caller's library (meta_list_media). |
media_path | text | no | none | A file inside one of the server's media folders, when an administrator has named folders (see server_status). |
dry_run | true or false | no | true | true = preflight only (default). false = publish the story now, after the user confirms. |
meta_post_to_instagram
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Post to an Instagram Business account: an image, a reel, a story or a carousel.
Instagram publishing is two steps - Meta fetches the media into a container, then the container is published. By default the call stops at the container, which is the draft: call meta_publish_draft within 24 hours to go live, after which it expires by itself. publish_now=true publishes it at once.
Instagram has no scheduling of its own, so schedule_at puts the post in this server's queue instead: nothing is sent to Meta until that time, when the server publishes it and makes every check again. A media URL has to still work then, and a library file still be in the library. The queued post is on the Queue page of the management site; queue_list, queue_reschedule and queue_cancel manage it.
Media is a public https URL, or a file from the caller's library (meta_list_media). A library video is uploaded to Instagram directly. A library image cannot be: Instagram only fetches images from a public URL, so one works only when this server has a public https address, and is refused with the reason otherwise. Images must be JPEG: a library PNG is refused unless auto_convert=true, which posts a JPEG copy of it. A library video's length and frame size are read from the file and checked; one at a URL is not inspected.
A reel's cover is chosen when it is posted and cannot be changed through the API afterwards (only in the Instagram app). Give an image (cover_url or cover_media_id) or a frame of the video (thumb_offset); with none, Instagram uses the first frame.
The extras (share_to_feed, collaborators, user_tags, location_id, audio_name, alt_text) are each for some kinds of post only, and one given for another kind is refused rather than dropped. None of them can be changed through the API once the post is made.
first_comment is posted as the account's own comment right after the post goes live: it is public at once, so show it to the user with the caption. It needs comments to be switched on for this installation. If Instagram refuses the comment the post is still live: the answer says first_comment "failed" and why, nothing is tried again, and the post must not be made a second time. With a draft it is kept and posted by meta_publish_draft; with schedule_at it travels with the queued post.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Instagram Business account id from meta_list_accounts. | |
caption | text | no | "" | The caption text. Needed for everything but a story: a story shows no caption, so leave it out there (one that is given is not sent). |
image_url | text | no | none | Public https URL of a JPEG, for IMAGE and STORIES. |
video_url | text | no | none | Public https URL of an MP4, for REELS and STORIES. |
media_id | text | no | none | A library image or video instead of a URL (meta_list_media). |
media_path | text | no | none | A file inside one of the server's media folders, a full path or one relative to a folder, when an administrator has named folders. |
media_type | one of IMAGE, REELS, STORIES, CAROUSEL | no | "IMAGE" | IMAGE, REELS, STORIES or CAROUSEL. |
carousel_urls | list of text | no | none | For CAROUSEL, 2 to 10 items in order, each a public https URL or a media_id from the library. A URL ending .mp4 or .mov is sent as a video. |
auto_convert | true or false | no | false | true = convert a library or media-folder image that is not a JPEG to JPEG for this post (transparency becomes white; the library keeps the original). false (default) = refuse it. Does nothing for an image at a URL. |
cover_url | text | no | none | For REELS, public https URL of a JPEG to use as the cover (9:16 recommended, up to 8 MB). |
cover_media_id | text | no | none | For REELS, a library image as the cover instead of a URL. Like any library image it needs this server's public https address, and a PNG needs auto_convert=true. |
thumb_offset | whole number | no | none | For REELS, the frame to use as the cover, in milliseconds from the start of the video. Give this or a cover image, not both. |
share_to_feed | true or false | no | none | For REELS. true = the reel can show in the feed as well as on the Reels tab, false = the Reels tab only. Left out, Instagram decides. |
collaborators | list of text | no | none | For IMAGE, REELS and CAROUSEL, up to 3 usernames to invite as collaborators. The post shows on a collaborator's profile once they accept. |
user_tags | list of object | no | none | For IMAGE, REELS and STORIES, public accounts to tag: [{"username": "nama", "x": 0.5, "y": 0.8}]. x and y are where the tag sits, each from 0 to 1 from the top left; required for an image, optional otherwise. |
location_id | text | no | none | For IMAGE, REELS and CAROUSEL, the id of a Facebook Page that has a location, to tag the post with that place. |
audio_name | text | no | none | For REELS, a name for the reel's audio. Instagram lets it be renamed once. |
alt_text | text | no | none | For IMAGE, a description for people who cannot see the image, up to 1,000 characters. |
first_comment | text | no | none | Text to post as the account's own first comment once the post is live. Not for STORIES. Held to the reply length limit. |
publish_now | true or false | no | false | true = publish as soon as the container is ready. false (default) = stop at the container, a draft, unless schedule_at is given. |
schedule_at | text | no | none | Queue the post on this server and publish it at this time, ISO 8601 (e.g. 2026-10-01T09:30:00+02:00) or a Unix timestamp, up to 90 days ahead. Cannot be combined with publish_now. |
dry_run | true or false | no | true | true = preflight only (default). false = actually create it, after the user confirms. |
meta_publish_draft
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Take a post that is not live yet live now: a draft, or a scheduled Facebook post ahead of its time.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
kind | one of facebook, instagram | yes | "facebook" for a Page post, "instagram" for a media container. | |
target_id | text | yes | The Page id, or the Instagram account id. | |
draft_id | text | yes | The post_id or creation_id returned when the post was created, or a post id from meta_list_posts. | |
dry_run | true or false | no | true | true = preflight only (default). false = publish it, after the user confirms. |
meta_cancel_draft
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Discard a Facebook Page post that has not gone live - a draft or a scheduled post.
This refuses anything already published, so it can only ever remove something no one has seen. There is no equivalent for Instagram: an unpublished container expires by itself within 24 hours, so leaving it alone is the way to discard it.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page the post belongs to. | |
post_id | text | yes | Post id from meta_list_posts. | |
dry_run | true or false | no | true | true = preflight only (default). false = discard it, after the user confirms. |
meta_update_scheduled_post
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Change a Facebook Page post that is scheduled and not live yet: move it to another time, change its text, or both.
This refuses a post that is already live. To publish a scheduled post now use meta_publish_draft, and to drop it use meta_cancel_draft. Find scheduled posts with meta_list_posts (state: "scheduled").
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page the post belongs to. | |
post_id | text | yes | Post id from meta_list_posts, or the one returned when it was scheduled. | |
schedule_at | text | no | none | The new time, ISO 8601 or a Unix timestamp, 10 minutes to 30 days ahead. |
message | text | no | none | The new text (the description, for a video). Replaces the old text. |
dry_run | true or false | no | true | true = preflight only (default). false = change it, after the user confirms. |
meta_update_post
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Change the text of a Facebook Page post that is already live. People who have seen the post see the new text, and Facebook marks the post as edited.
Meta only lets an app edit a post that the same app made: a post published through this server can be edited, one written in Facebook or Business Suite is refused by Meta. Only the text changes; a post's photo, video or link cannot be replaced. A post that is scheduled and not live yet is changed with meta_update_scheduled_post instead. Instagram has no edit at all: a caption cannot be changed through the API, only by deleting the post and posting it again, which loses its comments and figures.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page the post belongs to. | |
post_id | text | yes | Post id from meta_list_posts (<page>_<post>). | |
message | text | yes | The new text. It replaces the old text whole. | |
dry_run | true or false | no | true | true = preflight only (default). false = change it, after the user confirms. |
meta_hide_post
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Take a live Facebook Page post off the Page's timeline, or put it back with hidden=false.
Nothing is deleted: the post keeps its comments and figures and its link still opens it, and it can be shown again at any time. That makes this the thing to do first when a post should come down - prefer it to meta_delete_post. Facebook only; Instagram has no hidden state through the API.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page the post belongs to. | |
post_id | text | yes | Post id from meta_list_posts (<page>_<post>). | |
hidden | true or false | no | true | true to hide (default), false to show it again. |
dry_run | true or false | no | true | true = preflight only (default). false = apply it, after the user confirms. |
meta_delete_post
Kind: write. It only previews the change unless dry_run is false. Removing needs confirm_remove to be true as well. Not offered while the server is in read-only mode.
Delete one published post for good: a Facebook Page post, or an Instagram post, reel, story or whole carousel. It cannot be undone, and the post's comments, reactions and figures go with it.
For a Facebook post, hide it first (meta_hide_post): that takes it off the timeline and can be undone. Delete only when the user asked for this post to be deleted, after showing it to them. One post per call. The post as it was - its text, link, time and counts - is kept in this server's activity log. Deleting does not give the day's post back, and a post that is not live yet is discarded with meta_cancel_draft instead.
Deleting an Instagram post needs a permission of its own (instagram_manage_contents), which this installation asks for only once an administrator has switched it on; the refusal says where. Instagram cannot delete one picture of a carousel, or a post that is running as an ad. A post made only to be advertised is refused here: deleting it stops the ad.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
post_id | text | yes | From meta_list_posts: a Page post id (<page>_<post>) or an Instagram media id. | |
page_id | text | no | none | The Page the post belongs to. |
ig_account_id | text | no | none | Or the Instagram account it belongs to. Give one or the other. |
confirm_remove | true or false | no | false | Must be true, and only when the user asked for a delete. |
dry_run | true or false | no | true | true = preflight only (default). false = delete it, after the user confirms. |
meta_reply_to_comment
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Reply publicly to a comment, as the Page or the Instagram account.
A reply goes live at once - there is no draft for a comment - so show the user the comment and the proposed reply, and get their confirmation for each one before dry_run=false. Replies have their own daily cap, separate from posts.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
comment_id | text | yes | From meta_list_comments or meta_list_new_comments. | |
message | text | yes | The reply text. | |
page_id | text | no | none | The Page whose post the comment is on. |
ig_account_id | text | no | none | Or the Instagram account whose media it is on. Give one or the other. |
dry_run | true or false | no | true | true = preflight only (default). false = post the reply, after the user confirms. |
meta_hide_comments
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Hide comments, or unhide them with hidden=false.
A hidden comment stays visible to the person who wrote it and their friends, and can be unhidden at any time - which is why this is the way to deal with a bad comment. Prefer hiding to arguing, and to deleting.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
comment_ids | list of text | yes | Up to 50 ids from meta_list_comments or meta_list_new_comments. | |
page_id | text | no | none | The Page whose posts the comments are on. |
ig_account_id | text | no | none | Or the Instagram account. Give one or the other. |
hidden | true or false | no | true | true to hide (default), false to unhide. |
dry_run | true or false | no | true | true = preflight only (default). false = apply it, after the user confirms. |
meta_delete_comment
Kind: write. It only previews the change unless dry_run is false. Removing needs confirm_remove to be true as well. Not offered while the server is in read-only mode.
Delete one comment for good, on a Page post, an Instagram post or an ad. It cannot be undone, and it is refused unless an administrator has allowed deleting comments on this installation.
Hide first (meta_hide_comments): a hidden comment is out of sight and can be brought back. Delete only when the user asked for this comment to be deleted, after showing it to them. The comment's replies go with it. The comment as it was is kept in this server's activity log.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
comment_id | text | yes | From meta_list_comments, meta_list_new_comments or meta_ads_list_ad_comments. | |
page_id | text | no | none | The Page whose post the comment is on. |
ig_account_id | text | no | none | Or the Instagram account whose media it is on. Give one or the other. |
confirm_remove | true or false | no | false | Must be true, and only when the user asked for a delete. |
dry_run | true or false | no | true | true = preflight only (default). false = delete it, after the user confirms. |
meta_set_instagram_comments
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Turn comments on or off for one Instagram post.
Turning them off hides nothing already there and deletes nothing; turning them back on restores the post as it was. Facebook Page posts have no equivalent in the API.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
ig_account_id | text | yes | Instagram Business account id from meta_list_accounts. | |
media_id | text | yes | The post, from meta_list_posts. Not a carousel item or a live video. | |
enabled | true or false | yes | false to turn comments off, true to turn them back on. | |
dry_run | true or false | no | true | true = preflight only (default). false = apply it, after the user confirms. |
meta_inbox_reply
Kind: write. It only previews the change unless dry_run is false. Not offered while the server is in read-only mode.
Reply to one person in one conversation, by private message, as the Page or its Instagram account. A message is private, arrives at once and cannot be recalled or deleted from here: show the user the conversation (meta_inbox_read) and the proposed reply, and get their confirmation for each one before dry_run=false. Never send the same text to several people; there is no bulk send and no first message - only a reply.
Meta lets a Page reply for 24 hours after the person last wrote. The conversation is read first and a reply outside that window is refused, with when it closed; only the person writing again reopens it. The recipient must be the other participant of the conversation. Messages have their own daily cap, separate from posts and from comment replies. Until the Meta app has Advanced Access for the messaging permissions, a message reaches only people who have a role on the app.
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
page_id | text | yes | The Page, from meta_list_accounts (for Instagram, the Page the account is linked to). | |
platform | one of messenger, instagram | yes | messenger or instagram. | |
recipient_id | text | yes | The person's id, from the same row of meta_inbox_list as conversation_id. | |
conversation_id | text | yes | From meta_inbox_list. | |
message | text | yes | The reply, plain text. | |
dry_run | true or false | no | true | true = preflight only (default). false = send it, after the user confirms. |