Your AI tool gets 33 tools from Heropost. It decides which ones to call from what you ask; you don't call them by name. This page is for checking what a tool can do, and for developers calling Heropost from their own code.
At a glance#
| Tool | What it does | Uses | Needs | Goes out |
|---|---|---|---|---|
get_workspace_info |
The workspace, this link's permissions, actions used, plan limits | Free | ||
list_social_accounts |
Accounts this link may use, and which need attention | Free | ||
get_brand_kit |
Brand voice, colors, fonts and logos | Free | ||
update_brand_kit |
Replace the brand kit's colors, fonts and logos | Free | ||
update_brand_voice |
Replace the brand voice | Free | ||
get_workspace_knowledge |
Facts saved about your business | Free | ||
update_workspace_knowledge |
Save or remove business facts | Free | ||
create_post |
Save one post as a draft | 1 action | ||
create_posts |
Save up to 25 posts as drafts | 1 action per post | ||
update_post |
Edit a draft or scheduled post | Free | Publish and schedule, for posts that aren't drafts | |
delete_post |
Delete a post from Heropost | Free | Publish and schedule, for posts that aren't drafts | |
schedule_post |
Schedule a draft | Free | Publish and schedule | Yes |
schedule_posts |
Schedule up to 50 drafts | Free | Publish and schedule | Yes |
publish_post |
Publish a post now | Free | Publish and schedule | Yes |
submit_post_for_approval |
Send a draft for review | Free | ||
list_posts |
Posts by status | Free | ||
get_posts_by_date_range |
Posts in a date range: the calendar | Free | ||
get_post_status |
Whether a post went out on each account, and why not | Free | ||
list_media |
Browse or search the Media Library | Free | ||
upload_media |
Add a photo or video from a public link | Free | ||
generate_image |
Make an image with Hero_Photo | 1–2 photo credits | ||
list_media_subjects |
Saved products, people and styles | Free | ||
upsert_media_subject |
Create or update a subject | Free | ||
delete_media_subject |
Delete a subject | Free | ||
list_inbox_threads |
Comments, messages and mentions | Free | Read the inbox; Growth or higher | |
get_inbox_thread |
One conversation in full | Free | Read the inbox; Growth or higher | |
manage_thread |
Mark a thread read, done or bookmarked | Free | Read the inbox; Growth or higher | |
reply_to_thread |
Reply to a comment or message | 1 action | Reply in the inbox; Pro or Agency | Yes |
get_performance_summary |
Totals compared with the previous period | Free | ||
get_top_posts |
Your best posts | Free | ||
get_format_insights |
Results by format | Free | ||
get_best_times |
Your best days and hours | Free | ||
get_follower_growth |
Followers over time | Free |
Needs is a switch under Your tools → Permissions and, for the inbox, the workspace owner's plan. An empty cell means every link can use the tool. Goes out marks the tools that put something in front of your audience. See Links, permissions and activity.
How the tools work#
- One workspace. Every tool works in the workspace the link belongs to, within its permissions and accounts.
- Ids are numbers. Get account ids from
list_social_accounts, post ids fromcreate_postorlist_posts, media ids fromlist_media,upload_mediaorgenerate_image, and thread ids fromlist_inbox_threads. - Scheduled dates (
scheduledDate) are ISO 8601 date-times. Without a time zone (2026-10-16T09:00:00) Heropost uses the workspace's time zone; withZor an offset (2026-10-16T09:00:00Z) it uses the time as given. Seconds are dropped, and the time must be more than 10 seconds ahead. - Analytics and calendar dates are UTC. Analytics take a date (
2026-10-01) or a date-time;get_posts_by_date_rangetakes date-times. - Network values:
FACEBOOK,INSTAGRAM,X,LINKED_IN,PINTEREST,YOU_TUBE,GOOGLE_MY_BUSINESS,REDDIT,TELEGRAM,TIK_TOK,THREADS,BLUESKY. The analytics tools also acceptTWITTER,LINKEDIN,YOUTUBE,GMBandTIKTOK. - Post statuses:
DRAFT,SCHEDULED,IN_PROGRESS,POSTED,PENDING_APPROVAL. - Titles are cut to 50 characters. On most networks the title is only for you; on YouTube it's the video title.
- Hints for your AI tool: reading tools are marked read-only.
delete_postanddelete_media_subjectare marked destructive. Many AI tools use these marks to decide when to ask you first. - Errors come back as a plain sentence the AI tool can act on, such as "limit must be between 1 and 300.". Every message: Limits, rate limits and error messages.
The post object#
The post tools return posts in this shape:
{
"id": 5012,
"title": "Autumn sale",
"postStatus": "DRAFT",
"scheduledDate": "2026-10-16T07:00:00Z",
"postedDate": null,
"updatedDate": "2026-10-08T14:02:00Z",
"text": "Our autumn sale starts Friday…",
"firstComment": null,
"url": null,
"hasPostingFailure": false,
"media": [{ "id": 880, "url": "…", "thumbUrl": "…", "mediaType": "PHOTO", "name": "sale.jpg", "index": 0 }],
"postItems": [{ "id": 1, "social": "INSTAGRAM", "publishingStatus": "…", "enabled": true }]
}
text, firstComment and media are what the post publishes. A network in postItems lists its own text or media only when it publishes something different, because it was changed in the post editor. A long caption in a list comes back shortened, with textTruncated.
A typical flow#
list_social_accountsto get account ids.list_media,upload_mediaorgenerate_imageif the post needs a picture.create_post(orcreate_posts) to save drafts.schedule_post(orschedule_posts) orpublish_postwhen you've asked for it to go out.get_post_statusto check the result on each account.
Workspace and brand#
get_workspace_info#
The workspace this link is connected to: its name, time zone, approval setting and brand voice; this link's permissions and accounts; actions used this month; and the plan's limits.
Uses: free · Needs: any link · Parameters: none
Returns { agent: { connectionId, workspaceId, connectionName, canPublish, canEngageRead, canEngageReply, accountIds, actionsUsedThisMonth, actionsLimit, timeZone }, workspace: { id, name, timeZone, approvalPolicy, brandVoice }, planUsage: { tier, features: [{ feature, limit, unlimited, used }] } }. accountIds is null when the link may use every account; actionsLimit is null when actions are unlimited.
Try "What can you do in my Heropost workspace?" · "How many AI actions have I used this month?"
list_social_accounts#
The social accounts this link may use: id, name, handle, network, followers at the last sync (not live), and whether each needs attention. Active accounts are listed in full. Paused accounts and accounts that need reconnecting can't publish: they're counted, and up to 10 are shown under needsAttention. Drafts can still be saved for them.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
search |
string | No | Matches the account name or handle. Not case-sensitive; a leading @ is ignored. |
social |
string | No | Network value, as shown on each account, e.g. FACEBOOK, INSTAGRAM, LINKED_IN. |
includePaused |
boolean | No | Also list paused and disconnected accounts, in short form. Default false. |
limit |
integer | No | 1–300. Default 200. |
Returns { workspaceId, accounts: [{ id, name, userName, social, logoPath, url, isPaused, pausedReason, needsReconnect, accountDetails: { numberOfFollowers } }], activeCount, returnedCount, truncated, hint, needsAttention: { count, accounts, note } }. Accounts outside this link's Which accounts choice aren't included.
Errors "limit must be between 1 and 300."
Try "Show my Heropost accounts" · "Which of my accounts need reconnecting?"
get_brand_kit#
The brand kit: brand voice, colors (hex and label), fonts, and logo variants (Media Library photos labeled, for example, primary, dark or icon).
Uses: free · Needs: any link · Parameters: none
Returns { brandKit: { workspaceId, brandVoice, logoPath, colors: [{ hex, name }], fonts: [{ family, role }], logos: [{ mediaId, label, url, thumbUrl, name, width, height }] }, note }
Try "What are our brand colors and fonts?"
update_brand_kit#
Replaces the brand kit's colors, fonts and logos with exactly what's sent. Anything left out is removed, so the tool should read the kit with get_brand_kit first. The brand voice is changed with update_brand_voice.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
colors |
array of { hex, name } |
Yes | #RRGGBB; up to 20; the first is the primary color; name up to 50 characters. [] clears. |
fonts |
array of { family, role } |
Yes | role is HEADING, BODY or OTHER; up to 10; family up to 100 characters. [] clears. |
logos |
array of { mediaId, label } |
Yes | Media Library photo ids; up to 10; label up to 50 characters. [] clears. |
Returns { brandKit }, as in get_brand_kit.
Errors "Color hex '{value}' is invalid — use #RRGGBB form, e.g. #1A73E8." · "Each font needs a family name, e.g. 'Montserrat'." · "Each font role must be HEADING, BODY or OTHER." · "Each logo needs the mediaId of a workspace library photo (see list_media)."
Try "Add #1A73E8 as our primary brand color and keep the others."
update_brand_voice#
Replaces the workspace's brand voice: the description of tone and style used when writing for this workspace. It replaces the whole text, so include everything that should stay.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
brandVoice |
string | Yes | The full description: tone, vocabulary, emoji use, do's and don'ts. Up to 4,000 characters. |
Returns { id, brandVoice }
Errors "brandVoice must not be empty. Provide the full brand voice description to set." · "brandVoice is too long — maximum 4000 characters. Shorten it and retry."
Try "Set our brand voice to warm, local and a little playful; short sentences, no emojis."
get_workspace_knowledge#
The facts Heropost has saved about your business: brand, offer, audience, voice, content pillars, formats, competitors, goals, language, posting times and things to avoid. Each has a key, value, confidence (0–100) and source. These are the same facts Hero_Agent uses on Home. An empty list means nothing has been saved.
Uses: free · Needs: any link · Parameters: none
Returns { workspaceId, items: [{ key, value, confidence, source, updatedDate }] }
Try "What does Heropost know about my business?"
update_workspace_knowledge#
Saves facts about your business. Keys that are sent are created or updated, removeKeys are deleted, and everything else stays. It's meant for what you said or what a document contained, never guesses or private data.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
items |
array of { key, value, confidence, source } |
One of items or removeKeys |
Up to 40 per call. key: a short lowercase slug such as brand, offer, audience, voice, pillars, formats, competitors, goals, language, posting-times, cta, do-not. value: up to 4,000 characters. confidence: 100 = you said it, 70 = from a document, 50 = inferred. source: questionnaire, document or agent. |
removeKeys |
string[] | One of items or removeKeys |
Keys to delete. |
Returns { workspaceId, items }
Errors "Provide items to save and/or removeKeys to delete." · "Save at most 40 knowledge items per call."
Try "Remember that we're closed on Mondays and our best seller is the almond croissant."
Drafts#
create_post#
Saves a post as a draft for one or more accounts. Nothing is scheduled or published. One post is one action, however many accounts it's for.
Uses: 1 action · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
text |
string | Yes | The caption. |
accountIds |
integer[] | Yes | Account ids from list_social_accounts. |
title |
string | No | Up to 50 characters; longer titles are shortened. Set it for YouTube: it's the video title. |
scheduledDate |
string | No | ISO 8601. Stored on the draft; schedule_post schedules it. |
firstComment |
string | No | Published as the first comment under the post. |
mediaIds |
integer[] | No | Media ids to attach, in order. |
Returns { post, attachedMediaIds, note }
Errors
- "accountIds is required. Call list_social_accounts to get the account ids in this agent key's scope."
- "Account id(s) {ids} were not found in this workspace. Call list_social_accounts to get the valid account ids for this agent key."
- "Account id(s) {ids} are outside this agent key's account scope. Call list_social_accounts to see the accounts this key may post to."
- "scheduledDate {date} is not in the future (it is now {time}Z, UTC). Pick a later time, or leave scheduledDate out to save the draft without one."
- "Draft post {id} was created, but a later setup step failed: {reason} Fix the issue and retry with update_post (postId {id}), or call delete_post {id} to discard the draft."
Try "Use Heropost to create a draft post for Friday about our autumn sale on Instagram."
Example arguments:
{
"text": "Our autumn sale starts Friday: 20% off everything in store.",
"accountIds": [101, 102],
"scheduledDate": "2026-10-16T09:00:00",
"firstComment": "Details on our website."
}
create_posts#
Saves up to 25 posts as drafts in one call, for bulk work from a spreadsheet, a CSV or a list. Each row works like create_post. Rows that fail are reported one by one, and the rest are still created. Nothing is scheduled: call schedule_posts with the new ids.
Uses: 1 action for each post created · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
posts |
array of rows | Yes | 1–25 rows, in order. |
Each row:
| Field | Type | Required | Description |
|---|---|---|---|
row |
integer | No | Your row number, returned with the result. |
text |
string | Yes | The caption. |
accountIds |
integer[] | Yes | Account ids. |
title |
string | No | Up to 50 characters. |
scheduledDate |
string | No | ISO 8601, stored on the draft. |
firstComment |
string | No | The first comment. |
url |
string | No | A link, shown as a link preview. |
mediaIds |
integer[] | No | Media ids to attach. |
mediaUrls |
string[] | No | Public links to photos or videos, uploaded first. Each must end in the file's extension, such as .jpg or .mp4. |
Photos from mediaUrls are added to the Media Library. Videos are kept for posting only: they don't appear in the library and have no cover image, so they can't be used for Pinterest or Reddit video posts.
Returns { createdCount, failedCount, created: [{ row, post }], failed: [{ row, error }] }
Errors "posts is required." · "Max 25 posts per create_posts call — split the batch." · per row: "text is required.", "accountIds is required.", "Media URL is not valid: {url}", "Media URL has no file extension, so its type can't be determined: {url}. Use a direct link ending in .jpg, .png, .mp4, …"
Try "Here's my content calendar CSV. Use Heropost to create all 20 posts as drafts."
Example arguments:
{
"posts": [
{ "row": 1, "text": "Monday tip: …", "accountIds": [101], "scheduledDate": "2026-10-19T09:00:00", "mediaUrls": ["https://example.com/images/tip-1.jpg"] },
{ "row": 2, "text": "New on the blog: …", "accountIds": [101, 102], "url": "https://example.com/blog/autumn" }
]
}
update_post#
Changes a draft or scheduled post. Only the fields sent change. text, firstComment, url and media apply to the whole post: networks that had their own version all get the new one. Media can only be changed on drafts. To remove all media, use the post editor.
Uses: free · Needs: any link for drafts; Publish and schedule for posts that are scheduled, published or waiting for approval
| Parameter | Type | Required | Description |
|---|---|---|---|
postId |
integer | Yes | The post. |
text |
string | No | New caption. |
title |
string | No | New title, up to 50 characters. |
firstComment |
string | No | New first comment. |
scheduledDate |
string | No | New date and time, ISO 8601. |
url |
string | No | New link. |
mediaIds |
integer[] | No | Media Library ids to add, in display order. |
replaceMedia |
boolean | No | true removes the current media first, so mediaIds replace it. Default false. |
Returns the post, as it will publish.
Errors "replaceMedia needs mediaIds — to remove all media from a post, use the post editor." · "Media can only be changed on draft posts (this post is {status}). Set it back to draft first, or change the media in the post editor." · "This agent key is draft-only — it can't modify a post that has already been scheduled, published, or submitted for approval. …"
Try "Make Friday's draft shorter and add our sale link."
delete_post#
Deletes a post from Heropost. This can't be undone. A post that's already published stays on the network: delete it there if you need to.
Uses: free · Needs: any link for drafts; Publish and schedule for other posts · Marked: destructive
| Parameter | Type | Required | Description |
|---|---|---|---|
postId |
integer | Yes | The post. |
Returns { postId, deleted: true }
Try "Delete the duplicate draft for Tuesday."
Scheduling and publishing#
schedule_post#
Schedules a draft to publish automatically at its date. If the workspace requires approval, the post must be approved first (see submit_post_for_approval).
Uses: free · Needs: Publish and schedule · Goes out: at the scheduled time
| Parameter | Type | Required | Description |
|---|---|---|---|
postId |
integer | Yes | The draft. |
scheduledDate |
string | No | ISO 8601. Without it, the date stored on the draft is used. |
Returns { id, postStatus, scheduledDate }
Errors The network's rules are checked here, with the same messages as in the app, such as "Unable to post because Instagram requires media." Also the date errors under create_post, "This agent key is draft-only — it can't publish or schedule posts. …", "This workspace requires human approval before posts can be scheduled or published. …" and "Post {id} is pending approval. It must be approved or rejected in Team > Approvals before it can be scheduled or published."
Try "Schedule that draft for Friday at 9am."
schedule_posts#
Schedules up to 50 drafts in one call. An AI tool that asks before each tool call asks you once for the whole batch. Each works like schedule_post. Failures are reported per post, and the rest are still scheduled.
Uses: free · Needs: Publish and schedule · Goes out: at the scheduled times
| Parameter | Type | Required | Description |
|---|---|---|---|
postIds |
integer[] | Yes | Up to 50 draft ids. |
scheduledDates |
string[] | No | New dates, matched to postIds by position. Leave an entry null or empty to keep that post's stored date. |
Returns { scheduledCount, failedCount, scheduled: [{ postId, post }], failed: [{ postId, error }] }
Errors "postIds is required." · "Max 50 posts per schedule_posts call — split the batch." · per post, the same as schedule_post.
Try "Schedule the drafts you made at their dates."
publish_post#
Publishes a post to its accounts now. Publishing finishes in the background: use get_post_status for the result on each account.
Uses: free · Needs: Publish and schedule · Goes out: now
| Parameter | Type | Required | Description |
|---|---|---|---|
postId |
integer | Yes | The post. |
Returns { postId, status: "PUBLISHING_STARTED", accountsDispatched, blocked: [{ account, reason }], note }. When Heropost held back every account, for example while a network limits one, status is "BLOCKED" and nothing was published; blocked gives the reason for each account.
Errors "Post {id} cannot be published because it is in the process of publishing or has already been published." · "Post {id} cannot be published because it has no active selected social networks to publish." · "Post {id} cannot be published because one or more of the selected social networks do not have active accounts." · the network rules and permission messages under schedule_post.
Try "Publish the launch post now."
submit_post_for_approval#
Sends a draft for review. It's needed before scheduling or publishing when the workspace requires approval, and it's how a link without Publish and schedule hands over finished drafts. A reviewer approves or rejects it in Team → My Approvals; approving a post with a future date also schedules it.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
postId |
integer | Yes | The draft. |
Returns { approval: { id, customPostId, status, createdDate }, note }
Try "Send Friday's post for approval."
Calendar and post status#
list_posts#
Lists the workspace's posts, optionally by status.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
status |
string | No | DRAFT, SCHEDULED, IN_PROGRESS, POSTED or PENDING_APPROVAL. |
take |
integer | No | 1–50. Default 20. |
skip |
integer | No | For paging. Default 0. |
Returns { totalCount, nodes: [{ id, title, postStatus, scheduledDate, postedDate, updatedDate, hasPostingFailure, textSnippet, postItems: [{ social, enabled }] }] }. textSnippet is the first 80 characters.
Errors "take must be between 1 and 50." · "skip must be 0 or greater."
Try "What drafts do I have in Heropost?"
get_posts_by_date_range#
The calendar: posts whose date falls in the range, in date order, including drafts, scheduled and published posts. Days with no results are empty days. The range includes both ends and can be up to 62 days. Up to 100 posts come back per call; up to 12 come back in full, and a longer list is an overview with shortened captions.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
from |
string | Yes | Start, ISO 8601 UTC, e.g. 2026-10-01T00:00:00Z. |
to |
string | Yes | End, ISO 8601 UTC, e.g. 2026-10-31T23:59:59Z. |
status |
string | No | A post status. |
skip |
integer | No | For ranges with more than 100 posts. |
Returns { totalCount, nodes: [post], note }. note says how to get the next page, or that captions were shortened.
Errors "from and to must be ISO 8601 dates, e.g. 2026-09-01T00:00:00Z." · "to must be after from." · "Date range cannot exceed 62 days. Request a shorter window." · "skip must be 0 or greater."
Try "What's on my calendar next week? Which days are empty?"
get_post_status#
A post's current status, with the result on each account and any posting errors.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
postId |
integer | Yes | The post. |
Returns { post, postingErrors }. Each account under post.postItems has id, name, publicationState, exceptionMessage (the network's error, if any) and linkToPost.
Errors "Post {id} was not found in this workspace."
Try "Did my Instagram post go out? Why did it fail?"
Media and Hero_Photo#
list_media#
Browses or searches the Media Library, newest first. Photos have an AI-written description, so query finds pictures by what they show. Results are ranked by how many words match.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | No | 2–6 words about what's in the picture or in the file name, e.g. beach sunset. Leave out to browse. |
mediaType |
string | No | PHOTO or VIDEO. Default both. |
orientation |
string | No | landscape, portrait or square. |
take |
integer | No | 1–50. Default 30. |
skip |
integer | No | For paging. |
source |
string | No | generated (made with Hero_Photo), uploaded or all (default). |
Searching and the orientation filter look at your newest 200 items.
Returns { totalCount, query, media: [{ id, name, mediaType, url, thumbUrl, width, height, orientation, description, matchedWords }], note }. With source: "generated", items also show generationId, preset, prompt and usedInPosts.
Errors "mediaType must be PHOTO or VIDEO." · "orientation must be landscape, portrait or square." · "source must be generated, uploaded or all."
Try "Find a beach sunset photo in my library for this post."
upload_media#
Adds a photo or video from a public link and returns its media id for create_post. Photos go into the Media Library. Videos are kept for posting only: they don't appear in the library, so keep the id, and they have no cover image, so they can't be used for Pinterest or Reddit video posts.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | A public link to the file. It must open without a sign-in. |
mediaType |
string | Yes | PHOTO or VIDEO. |
fileName |
string | Yes | With its extension, e.g. product-shot.jpg. |
Returns { media: { id, url, mediaType, name, thumbUrl, width, height, duration }, note }
Errors "mediaType must be PHOTO or VIDEO."
Try "Add this photo to my Heropost library and use it on Friday's draft: https://example.com/photo.jpg"
generate_image#
Makes one image with Hero_Photo and saves it to the Media Library and the Hero_Photo studio. Returns a media id to attach with create_post.
Uses: photo credits, not actions: 2 for a photo, 1 for a graphic · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt |
string | Yes | What to make: subject, setting, style, mood. 3–2,000 characters. |
kind |
string | No | PHOTO for photographic scenes (default, 2 credits) or GRAPHIC for text-heavy designs (1 credit). |
aspect |
string | No | SQUARE 1:1 (default), PORTRAIT 4:5, STORY 9:16, LANDSCAPE 16:9 or CLASSIC 4:3. |
subjectIds |
integer[] | No | Saved subjects whose photos guide the image, so the product or person looks right. Up to 6 are used. |
preset |
string | No | A Hero_Photo preset id, e.g. lifestyle-scene, clean-packshot, colour-block-hero, flat-lay, studio-headshot, new-keys. |
The tool refuses anything that costs more than 2 credits. Presets that make a video, several images or need typed text are in the Hero_Photo studio.
Returns { media, model, creditsUsed, creditsRemaining, note }. If the image takes longer than about 100 seconds: { generationId, status: "GENERATING", creditsUsed, creditsRemaining, note }; it then appears in list_media with source: "generated".
Errors "prompt must describe the image (at least 3 characters)." · "This needs {N} photo credits — you have {M}." · "{reason} The credits were returned." when it fails: the credits come back.
Try "Make a square photo of our matcha bottle on a sunny café table and attach it to Friday's draft."
Costs and credit packs: Hero_Photo credits.
list_media_subjects#
The workspace's saved subjects: named products, people and styles, with their reference photos. Subjects guide generate_image.
Uses: free · Needs: any link · Parameters: none
Returns { subjects: [{ id, name, description, kind, createdDate, media }], note }
Try "Which products have we saved for Hero_Photo?"
upsert_media_subject#
Creates a subject, or updates one when id is sent, using photos from the Media Library as references.
Uses: free · Needs: any link
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Unique in the workspace, e.g. Matcha Bottle. Up to 100 characters. |
kind |
string | Yes | PRODUCT, PERSON, STYLE or OTHER. |
mediaIds |
integer[] | Yes | Media Library photo ids, up to 20. Replaces the subject's current photos. |
id |
integer | No | The subject to update. Leave out to create one. |
description |
string | No | Details the image should keep. Up to 2,000 characters. |
Returns { subject }
Errors "kind must be PRODUCT, PERSON, STYLE or OTHER."
Try "Save our matcha bottle as a product, using these three library photos."
delete_media_subject#
Deletes a subject. Its photos stay in the Media Library.
Uses: free · Needs: any link · Marked: destructive
| Parameter | Type | Required | Description |
|---|---|---|---|
subjectId |
integer | Yes | From list_media_subjects. |
Returns { deleted: true, subjectId }
Try "Delete the subject for our old packaging. Keep the photos."
Social Inbox#
The inbox covers Facebook (comments, mentions, messages), Instagram (comments, mentions, messages; message replies go through the linked Facebook Page), LinkedIn and YouTube (comments), Google Business Profile (review replies) and Threads (replies and mentions). X isn't included.
Reading needs Read the inbox and the workspace owner on Growth or higher. Replying needs Reply in the inbox and Pro or Agency.
list_inbox_threads#
Lists inbox threads: comments, messages and mentions.
Uses: free · Needs: Read the inbox; Growth or higher
| Parameter | Type | Required | Description |
|---|---|---|---|
threadType |
string | No | COMMENT, DIRECT_MESSAGE or MENTION. |
isRead |
boolean | No | Filter by read. |
isDone |
boolean | No | Filter by done. |
isBookmarked |
boolean | No | Filter by bookmarked. |
take |
integer | No | 1–100. Default 20. |
skip |
integer | No | For paging. Default 0. |
Returns { threads: { totalCount, nodes: [{ id, threadType, participantName, isRead, isBookmarked, isDone, unreadCount, lastActivityAt, accountName, socialId, postCaption, postPermalink }] }, platformCapabilities, note }
Errors "take must be between 1 and 100." · "skip must be 0 or greater." · the inbox permission messages below.
Try "What comments and DMs are waiting for me?"
get_inbox_thread#
One thread with every message.
Uses: free · Needs: Read the inbox; Growth or higher
| Parameter | Type | Required | Description |
|---|---|---|---|
threadId |
integer | Yes | From list_inbox_threads. |
Returns { thread, platformCapability, note }. Each message has id, authorName, text, mediaUrl, isFromMe, platformTimestamp and sentByAgentConnectionId, which is set when a Heropost AI agent, such as a connected AI tool, sent the message.
Try "Show me the whole conversation with that customer."
reply_to_thread#
Replies to a comment or message, as your account. Text only. LinkedIn and YouTube take comment replies only, and Google Business Profile review replies only. Heropost records the reply as sent by your AI tool.
Uses: 1 action · Needs: Reply in the inbox; Pro or Agency · Goes out: now
| Parameter | Type | Required | Description |
|---|---|---|---|
threadId |
integer | Yes | The thread. |
message |
string | Yes | The reply. |
Returns { id, text, isFromMe, platformTimestamp, sentByAgentConnectionId }
Try "Reply to Anna's comment and thank her."
manage_thread#
Marks a thread read or done, or turns its bookmark on or off.
Uses: free · Needs: Read the inbox; Growth or higher
| Parameter | Type | Required | Description |
|---|---|---|---|
threadId |
integer | Yes | The thread. |
action |
string | Yes | mark_read, mark_done or toggle_bookmark. |
Returns { threadId, action, result }
Errors "Unknown action. Valid actions: mark_read, mark_done, toggle_bookmark."
Try "Mark the comments you've answered as done."
Inbox permission messages:
- "This agent key doesn't have inbox access. The workspace owner can enable engagement in Heropost under Home > Connect your AI tools."
- "Agent inbox access requires an agent add-on plan (Agent Growth or higher). The workspace owner can add one in Heropost under Home > Connect your AI tools."
- "This agent key can't reply or react in the inbox. The workspace owner can enable replies in Heropost under Home > Connect your AI tools."
- "Agent inbox replies require the Agent Pro or Agent Agency add-on. The workspace owner can upgrade in Heropost under Home > Connect your AI tools."
Plans are changed in Billing; the switches are under Your tools → Permissions.
Analytics#
All five are free, work with any link and only cover the accounts the link may use. Results are collected for Facebook, Instagram, YouTube, LinkedIn and Threads. A null metric means the network doesn't provide it, not zero.
They share these parameters, all optional:
| Parameter | Type | Description |
|---|---|---|
from |
string | Start date, ISO 8601, e.g. 2026-08-01 or 2026-08-01T00:00:00Z. |
to |
string | End date, ISO 8601. Defaults to now. For the summary, top posts, formats and best times, the end date itself isn't included. |
socials |
string[] | Networks to include, e.g. ["INSTAGRAM"]. |
If your plan's analytics go back fewer days than asked, the tool is told: "Analytics on this workspace's plan cover the last {N} days. Ask again with from = {date} or later (a plain date, UTC). …"
Errors "from must be before to." · "{from or to} is not a valid ISO 8601 date: '{value}'. Use e.g. 2026-08-01 or 2026-08-01T00:00:00Z." · "Unknown social network(s): {values}. Valid values: …"
get_performance_summary#
Totals for a period (posts, reach, views, impressions, reactions, comments, shares, engagements, engagement rate) compared with the period right before it, with the change in percent. Default: the last 30 days.
Returns the current and previous totals and deltaPercent for each.
Try "How did Instagram do this month compared with last month?"
get_top_posts#
Your best posts in a period, ranked by engagements or views, each added up across the networks it went to. Default: the last 30 days, top 5 by engagements.
Extra parameters: sortBy (string: ENGAGEMENTS or VIEWS) and take (integer, 1–20, default 5).
Errors "take must be between 1 and 20." · "sortBy must be ENGAGEMENTS or VIEWS."
Try "What were my top 5 posts in the last 30 days?"
get_format_insights#
Results by format (video, image, carousel, text and so on). Default: the last 90 days. When insufficientData is true, or a format's sufficientSample is false, there are too few posts to draw conclusions.
Try "Do videos or carousels work better for me?"
get_best_times#
The days and hours (in the workspace's time zone) that did best, ranked by average engagements per post. Only slots with at least 2 posts count. Default: the last 90 days. dayOfWeek runs from 1 (Monday) to 7 (Sunday). insufficientData means there isn't enough history yet.
Try "What are my best times to post on LinkedIn?"
get_follower_growth#
Followers per account over time, from daily snapshots, with start and end totals and growth. Default: the last 30 days. Recently connected accounts have short histories.
Returns { from, to, accounts: [{ accountId, social, startFollowers, endFollowers, growth, growthPercent, snapshots: [{ date, followers }] }] }
Try "How many followers did we gain on Instagram this month?"
Calling the tools directly#
Any MCP client or SDK can call these tools.
| Address | https://mcp.heropost.io/mcp/hp_ag_xxxx… (key in the link), or https://mcp.heropost.io/ with the key in a header |
| Headers | Authorization: Bearer hp_ag_xxxx… or X-Agent-Key: hp_ag_xxxx… |
| Transport | MCP Streamable HTTP. Each request stands alone: there's no session to keep. |
| Sign-in | None. Heropost doesn't use OAuth. Errors before a tool runs come back as JSON: {"error": "…"}. |
| Server | Name heropost, title Heropost, version 1.0.0 |
| Request size | Up to 1,000,000 bytes per request |
Call tools/list to get all 33 tools with their input schemas, then tools/call. A tools/call request looks like this:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "create_post",
"arguments": {
"text": "Our autumn sale starts Friday.",
"accountIds": [101],
"scheduledDate": "2026-10-16T09:00:00"
}
}
}
When your client connects, Heropost also sends instructions for the AI: save posts with create_post (copy left in the chat doesn't exist in Heropost), use account ids from list_social_accounts, keep posts as drafts until the person clearly asks for them to go out and say which accounts they'll reach, remember that delete_post can't be undone, and that one created post or one inbox reply is one action.
Rate limits, sizes and every error: Limits, rate limits and error messages.
Questions#
Do I need to call these tools by name?
No. Ask your AI tool in plain words, and it picks the tools. You only call them by name from your own code. Prompts to try: Example prompts that work.
Which tools use an action?
Only create_post (1 action), create_posts (1 action for each post created) and reply_to_thread (1 action). generate_image uses photo credits instead. Every other tool is free.
Can a tool delete a post from Instagram or Facebook?
No. delete_post removes the post from Heropost only. A post that's already published stays on the network.
Is there a tool for Post Groups, automations or MonoL.ink?
No. Those stay in the Heropost app. Name the accounts you want instead of a Post Group.
Where do I get each tool's input schema?
Call tools/list. It returns all 33 tools with their input schemas. See Calling the tools directly.