API reference for agents
This single-document reference includes client setup, authentication, all MCP tool names and input fields, REST operations and examples, platform requirements, and completion rules. Read the sections below without following links to learn the API and MCP workflows. Links to tutorials and template-specific examples are supplementary. Retrieve each template's current inputs before generating a visual.
Connection and verification
For MCP, configure Streamable HTTP at
https://mcp.blotato.com/mcpwith OAuth or theblotato-api-keyheader supported by your client.For REST, use
https://backend.blotato.com/v2with theblotato-api-keyheader. Keep keys out of chat messages, documentation, and shared configuration.Verify MCP with
blotato_list_accounts, or REST withGET /v2/users/me/accounts. An empty account list is a successful authenticated result.Select social accounts from returned IDs. Connect accounts through Blotato Settings before publishing.
Reading this document does not install a server or authorize an account. An installed plugin with no connected account or no tools has not passed verification. OAuth authorization and a successful tool call are separate checks.
Execution rules
Use only tools exposed by the connected client. REST and MCP do not expose identical operations or argument shapes.
Read the selected tool's schema. Get account, Page, board, playlist, post, schedule, and template IDs from responses rather than inventing them.
Get the user's approval for the intended write operation. Do not publish, send messages, activate automations, delete content, or purchase credits as a connection test.
Pass public media URLs directly. For a local file, request upload URLs, PUT the bytes, verify upload success, then use the returned public URL.
Save returned IDs. Follow each operation's completion states below. A submitted or scheduled request is not proof of publication.
After an uncertain write response, check existing work before retrying. A repeated create request risks duplicate content.
Report the returned status, error, scheduled time, or published URL. Do not claim unsupported features or unverified client compatibility.
Contents
Use Blotato with an AI agent
This is the entry point for customer assistants executing tasks and support agents answering questions. Website instructions describe actions an agent performs or explains to the customer. They are not interchangeable with REST or MCP calls.
Route the request
Use context already supplied. Ask only for a missing fact which changes the next action.
Identify the requested outcome and whether you are executing it or explaining it.
Identify the surface: Blotato website, MCP, REST, n8n, or Make.
Identify the client, destination platform, and failing stage when relevant.
Identify the artifact: workflow JSON, local media file, hosted media URL, generated visual, draft, scheduled item, or published post.
Check which provider owns the endpoint, key, or node. A Blotato key does not authenticate another provider.
For support, follow Diagnose and answer. Answer the customer's question before offering a tutorial. Preserve completed checks and human corrections.
Website Modes and Current Navigation
Developer Platform is the website navigation for monitoring API, MCP, and automation work. Content Studio is the navigation for the in-app AI Agent and visual creation. Switching modes does not change the subscription, accounts, or content, and does not connect an external assistant.
In-app AI Agent: Content Studio > New Post. New draft inside the workspace creates a blank draft, not AI output.
Connect or reconnect social destinations: Accounts > Connect account, or the existing account's actions menu > Reconnect. Accounts is no longer a Settings tab.
Publication results: Posts > Scheduled, Published, or Failed. Select the platform and time window before concluding a post is missing.
Recurring slots: Calendar > Weekly schedule, within the Weekly posting schedule section.
Performance rankings: Analytics > Top posts, not the old Published > Top Performing tab.
API activity and errors: Developer Platform > Logs.
Comments and messages: Inbox > Posts or Chats.
Inspiration, Prompts, and Viral AI Coach: Tools.
Credentials and client setup: Settings > API. Language and reset controls: Settings > Profile. Credits and subscription: Settings > Billing.
Use Website modes and navigation for the screen-by-screen map and screenshots. The draft's Photo / Video control uploads existing media. Do not send users there to find the old image-generation menu.
Connect and verify
Select the exact client in MCP setup, or use the REST quickstart for HTTP, n8n, or Make.
Confirm paid access. Generating an API key during a trial starts billing. Read authentication before generating a key.
Call
blotato_list_accounts, orGET /v2/users/me/accounts.Select the requested social destination from the response. Connect missing accounts in Accounts.
An empty list proves authentication, not publishing readiness. A saved connector, OAuth redirect, or “Connected” label alone does not prove a tool call works. ChatGPT.com and Codex have separate setup paths.
Choose a task
Instructions for the agent
Use only available tools and the selected operation's schema. REST and MCP differ in fields and operation coverage.
Retrieve current IDs. After reconnection, re-list accounts. Never substitute a social-platform post ID, submission ID, or schedule ID for another ID type.
Check platform requirements and media requirements before a write.
Confirm the requested destination and authorization. Connection tests must not publish, send messages, purchase credits, or activate automations.
Record returned IDs. Use operation-specific completion rules, including error fields inside successful HTTP or MCP responses.
Inspect existing work after an uncertain write. Do not blindly repeat a create request.
Report the verified status, scheduled time, or returned media/public URL. Explain what remains unresolved.
Documentation for retrieval
Start with the task page, then retrieve only the contract or diagnosis needed.
Optional public documentation MCP lookup, separate from account access
Available tools and behavior
Required and optional tool arguments
Generated setup, contracts, examples, and completion rules in 1 document
Find a page outside this task index
Whole-corpus retrieval when required
Published REST schemas
Reading documentation does not install a server, authorize an account, or execute a task.
Search and read the help docs
Use the task index when the outcome is known. For another question, search published help pages through the documentation MCP server. This is an optional lookup route, not another requirement for publishing.
Choose the server
Look up published help
Public documentation. No Blotato API key or account authorization required.
Work with connected social accounts
https://mcp.blotato.com/mcp
Follow client setup and verify account access.
The documentation server does not connect social accounts or publish posts. Its results describe published documentation, not unpublished repository edits.
Find the answer
Add the documentation endpoint to an HTTP MCP client under a distinct name such as
blotato-docs, if a docs connection is needed.Discover its tools with
tools/list.Call
searchDocumentationwith aquerystring.Select a result for the customer's surface: API/MCP execution or Blotato website instructions.
Call
getPagewith the result's page URL inurl.Read the page before answering or constructing a request.
searchDocumentation
query
Retrieve matching help-page excerpts and URLs.
getPage
url
Retrieve the selected page's Markdown.
Example search input:
A search result about a website button is not an API parameter reference. A result about API scheduling is not a website walkthrough. Search rank alone does not establish relevance or correctness. Follow the task index when results mix surfaces.
Keep API keys and customer data out of documentation queries. Use search and page retrieval for lookup. The server also advertises askQuestion and sendFeedback. Feedback sends a report, so require the user's request before using it.
Without a docs MCP connection
Read the task index or documentation index.
Fetch the selected page as Markdown by appending
.mdto its published URL.
For account actions, return to Blotato client setup. Reading help documentation does not verify access to a customer's connected accounts.
The hosted documentation endpoint is provided by GitBook. See GitBook's published-docs MCP requirements.
Connect your AI client
Choose your client below. Blotato's MCP server runs remotely at https://mcp.blotato.com/mcp using Streamable HTTP.
Before you start
Confirm your paid Blotato subscription. API and MCP access is not included in the free trial.
Connect social accounts in Accounts.
For an API-key setup, copy the full key from Settings > API. Generating a key during a trial ends the trial and starts billing.
An account connection is needed for publishing. You still receive a successful empty account list before connecting social accounts.
Choose your client
Open Settings > API for the client chooser. Select the app you use, not another app with a similar chat interface. ChatGPT.com and ChatGPT Work / Codex have separate setup instructions. A Blotato subscription is separate from your AI client's subscription.
After setup, ask your client to list connected Blotato accounts. A Connected badge alone does not verify a tool call. A successful empty list means the connection works but no social accounts are connected.
Claude.ai
Open Claude connectors.
Add a custom connector named
Blotato.Enter
https://mcp.blotato.com/mcpas the URL.Connect and approve access in the browser.
Ask: “List my connected Blotato accounts using
blotato_list_accounts.”
Log into the intended Blotato account in the browser during authorization. If access fails, follow OAuth troubleshooting.
Claude Desktop / Cowork
Open Customize, then Connectors.
Add a custom connector named
Blotato.Enter
https://mcp.blotato.com/mcpas the URL.Connect and approve access in your browser.
Ask: “List my connected Blotato accounts using
blotato_list_accounts.”
On a managed workspace, ask the workspace admin if adding connectors is restricted. If authorization repeatedly fails after reconnecting, follow the stale-session steps.
For local media, the assistant also needs file access and permission to reach the upload destination. Follow upload troubleshooting.
Video: Claude Cowork and Desktop setup.
Claude Code
Run this command in your terminal:
Open Claude Code.
Run
/mcp.Select Blotato and authenticate through the browser.
Ask: “List my connected Blotato accounts using
blotato_list_accounts.”
For an API-key setup instead of OAuth, use this command when adding the server. Replace the placeholder with your full API key:
If Blotato is already configured, manage that entry through /mcp before adding it again. Keep API keys out of shared project configuration.
See Claude Code's MCP documentation and Blotato's Claude Code tutorials.
Codex
Open Settings, then MCP servers, and add a server.
Name it
blotato.Select Streamable HTTP.
Enter
https://mcp.blotato.com/mcpas the URL.Under Headers, set
blotato-api-keyto your full API key.Leave Bearer token env var blank when using the header above.
Save and restart the MCP connection or client.
Ask: “List my connected Blotato accounts using
blotato_list_accounts.”
For Codex CLI with OAuth:
For an API key in Codex's ~/.codex/config.toml, use TOML:
Replace the placeholder and keep the key in your personal configuration. The CLI also supports a bearer-token environment variable if your environment supplies it.
See OpenAI's MCP configuration guide.
ChatGPT.com / Work
Use OpenAI's custom MCP connection flow on ChatGPT.com:
Enable Developer mode in Settings → Security and login.
Open ChatGPT Plugins.
Select the + button.
Enter the name
Blotato, a description, and server URLhttps://mcp.blotato.com/mcp.Choose OAuth authentication.
Create the connection.
Complete the Blotato sign-in and review the requested access before approving.
Start a new chat with Blotato selected in the tools menu.
Ask: “List my connected Blotato accounts using
blotato_list_accounts.”
If the plugin exists but has no connected account, open Settings → Plugins → Blotato → Connect another account → Sign in with Blotato. Adding the plugin and authorizing an account are separate steps.
“No app tools available yet” means the setup has not passed verification. Check account authorization and tool discovery before retrying the prompt. If sign-in fails, record the error and follow authentication troubleshooting. Do not describe the connection as working until a tool call succeeds.
Availability depends on your account and workspace policy. This creates a custom connection, rather than installing a Blotato listing from the public directory. For local Codex configuration, use the Codex tab. Codex does not use ChatGPT.com's Developer mode toggle.
Cursor
Open your personal
~/.cursor/mcp.jsonconfiguration.Add the Blotato entry below, preserving any existing servers.
Replace
YOUR_API_KEYwith your full key.Save and restart Cursor.
Ask: “List my connected Blotato accounts using
blotato_list_accounts.”
Use Cursor's personal configuration for a literal API key. For variable substitution and workspace configuration, see Cursor's MCP documentation.
VS Code
For VS Code's MCP configuration:
Open
.vscode/mcp.jsonin your workspace, preserving any existing servers.Add the configuration below.
Start the Blotato server from the editor's MCP controls.
Enter your full Blotato API key when prompted.
Ask the chat assistant: “List my connected Blotato accounts using
blotato_list_accounts.”
This uses VS Code's servers format, rather than Cursor's mcpServers format. Interactive input variables apply to the extension host. For VS Code Agent Host configuration and restrictions, follow the VS Code MCP reference.
Other clients
For Antigravity, Replit Agent, or another remote-MCP client:
Open the client's MCP configuration.
Select Streamable HTTP.
Set the URL to
https://mcp.blotato.com/mcp.Complete OAuth if supported, or set a
blotato-api-keyheader to your full API key.Reload the connection.
Ask the assistant to call
blotato_list_accounts.
Some clients accept the JSON copied from Settings > API under Other MCP Clients. Check the client's configuration format before pasting it. Codex uses TOML, and VS Code uses a different JSON wrapper.
For a form with a Headers section, enter the full key as the value for blotato-api-key. Leave Bearer token env var blank when using this header.
Verify your connection
The verification call is blotato_list_accounts. It returns an array containing account IDs, platforms, names, and subaccounts. An empty array is a valid result when you have no connected accounts.
If no tool call runs, check whether the client enabled the connection. If the call returns an error, use the authentication guide and the troubleshooting steps below.
After verification, choose an agent workflow.
Tutorials
Upload your own local images or videos via MCP
The Blotato MCP tools, such as blotato_create_post, do not accept local file paths. Media must be a publicly accessible URL. Allowlisting egress to database.blotato.io is necessary but not enough on its own. You still upload the file first.
To use a local file:
Call
blotato_create_presigned_upload_urlwith your filename (include the extension). It returns apresignedUrland apublicUrl.Upload the raw file bytes to
presignedUrlwith an HTTPPUT(for examplecurl -X PUT "<presignedUrl>" --data-binary "@<local_file>"). Send raw bytes, not JSON and not multipart form data.Pass the returned
publicUrlin themediaUrlsfield ofblotato_create_post.
Do not pass the local file directly to blotato_create_post. If you allowlisted database.blotato.io but the upload still fails, the file was likely sent directly instead of being PUT to the presigned URL, or the PUT used the wrong body encoding.
Troubleshooting
If the MCP server connects but does not work as expected:
OAuth clients (Claude.ai, Desktop, Cowork, Claude Code): Make sure you are logged into your Blotato account in the browser. The OAuth approval requires an active Blotato session.
API-key connections (for example, Cursor or a Codex header configuration): Double check you copy/pasted the correct API key from Settings > API. Make sure there are no extra spaces or missing characters. If your key ends with one or more
=characters, copy the full key including the trailing=, since dropping it causes a 401 "invalid API key" error.Reload or restart the client after saving its MCP configuration.
OAuth authorization fails: Check the client-specific tab. If the client supports API-key headers, use that tab’s API-key configuration. Codex uses TOML and header form fields. Cursor uses JSON. Do not paste one client’s configuration into another client.
Give your assistant the agent reference and ask it to call
blotato_list_accounts. Reading documentation does not install the MCP server, authorize an account, or expose tools to a chat.If the connector shows "Connected" but a tool fails, inspect the returned error. A subscription-related
403requires an active paid plan. A401points to credentials or session authentication. Follow authentication checks. Generating an API key during a trial starts the paid subscription.An empty account list is a successful call. Connect a social account in Accounts before publishing.
For a JSON parsing error, use your editor's local JSON validation. Check for missing commas and unmatched braces. Do not paste configuration containing an API key into an online validator.
Connector shows "Connected" but never authenticates (stale connector session). If the Blotato connector in Claude Cowork or Claude Desktop shows Connected but every tool call fails with a credential error, and reconnecting does not help, the client is reusing a stale cached session. A simple reconnect reuses that same cached session, so remove it fully and add it fresh:
Go to Customize > Connectors and fully remove the Blotato connector
Click the + button, choose Add custom connector, and approve access again
To double-check the key itself, see Settings > API
"Access to this website is blocked by your network egress settings" during a presigned upload. Claude Cowork and Claude Desktop block outbound network access by default, so the
PUTto the presigned upload URL cannot reachdatabase.blotato.io. To allow it:Go to Claude Cowork/Desktop > Settings > Capabilities > Allow network egress
Set "Package managers only"
Under Additional allowed domains, add
database.blotato.ioand click AddFully quit and restart Claude Cowork/Desktop
If your settings look correct but the upload stays blocked, set Allow network egress to "Allow all" instead of "Package managers only", then restart and retry
Video walkthroughs: Claude + Blotato Beginner Setup and Build Your AI Personal Assistant for Social Media Marketing
API access and authentication
API and MCP access is included in paid Starter, Creator, and Agency subscriptions. The free trial does not include API or MCP access. Generating an API key during a trial ends the trial and starts the paid subscription.
REST API
Open Settings > API.
Generate or copy your API key.
Include the key in the
blotato-api-keyheader of each request.Call
GET https://backend.blotato.com/v2/users/me/accountsto verify access.
Copy the full key, including any trailing = characters. Preserve the value exactly. JSON values use double quotes. Store credentials in your client's secret settings or environment, outside published examples.
MCP
The server uses Streamable HTTP at https://mcp.blotato.com/mcp and accepts these authentication methods:
OAuth
Add the server URL and complete the browser authorization flow
API key header
Set blotato-api-key to your API key
Bearer header
Set Authorization to Bearer YOUR_API_KEY
Use the configuration supported by your client in the setup guide. A field named “Bearer token env var” expects an environment variable name, rather than the key itself. For a header-value form, paste the key into the header value.
After connecting, ask the assistant to call blotato_list_accounts. An empty array is a successful authenticated response with no connected accounts.
Resolve access errors
401 or invalid credentials
Recopy the full API key, or repeat OAuth authorization in the client
403 with a subscription message
Check the subscription in Billing
OAuth fails but an API-key request succeeds
Follow the OAuth session troubleshooting steps for the client
Accounts are missing
Confirm the Blotato account used to authorize, then check Social accounts
Use the returned error to choose the next step. An OAuth error alone does not establish a billing problem.
REST API versus MCP
Both interfaces use your Blotato account and subscription. Choose the interface your assistant or automation uses.
Use from
An assistant with MCP tools
HTTP code, n8n, Make, or other workflow tools
Connect to
https://mcp.blotato.com/mcp
https://backend.blotato.com/v2
Authenticate
OAuth or an API key, depending on the client
blotato-api-key header
Publish input
Tool arguments such as accountId, platform, text, and mediaUrls
A JSON body containing post.accountId, post.content, and post.target
Account lookup
blotato_list_accounts includes subaccounts
Fetch accounts, then fetch subaccounts when needed
Immediate post and source completion
Tools wait internally for up to 20 seconds, then return the available result
Submit, save the returned ID, and poll the status endpoint
Visual generation
Not supported at this time
Create with POST /v2/videos/from-templates, then poll the visual status endpoint
MCP tools expose a selected set of workflows. An endpoint in OpenAPI does not imply a corresponding MCP tool. For example, REST includes schedule-slot management and a webhook publishing target. MCP manages scheduled posts and publishes to the 9 listed social platforms, but does not expose these 2 REST capabilities.
Choose your setup
If your assistant already has
blotato_tools, call those tools directly using their schemas.If you are adding Blotato to an assistant, follow MCP setup.
If you are building HTTP requests, follow the REST quickstart.
Keep the 2 request shapes separate. Copying a REST post object into an MCP tool call fails when the tool expects flat arguments.
MCP input index
This field index covers the 32 tools listed by Blotato's MCP server. Use the connected tool schema for types, nested objects, allowed values, and defaults.
Required below means required by the tool-level input schema. Platform-specific conditions still apply. For example, Facebook needs a page ID and TikTok needs its privacy and disclosure fields. Follow the platform guides.
These are MCP arguments, not REST bodies. Read REST versus MCP before translating a request.
accountId, platform, name, dmMessage
pageId, triggers, buttons, followGate, emailGate, webhook, isActive
automationId
name, triggers, dmMessage, buttons, followGate, emailGate, webhook, isActive
accountId, platform, text
mediaUrls, additionalPosts, pageId, mediaType, link, replyControl, privacyLevel, disabledComments, disabledDuet, disabledStitch, isBrandedContent, isYourBrand, isAiGenerated, autoAddMusic, isDraft, imageCoverIndex, videoCoverTimestamp, boardId, title, altText, collaborators, coverImageUrl, shareToFeed, audioName, firstComment, trial, privacyStatus, shouldNotifySubscribers, isMadeForKids, containsSyntheticMedia, thumbnailUrl, playlistIds, scheduledTime, useNextFreeSlot
For results, workflow order, and recovery, use the tool reference and agent workflows.
Tools Reference
The Blotato MCP Server exposes 32 tools. Use the connected tool's input schema for its arguments. Start with client setup or choose an agent workflow.
Call blotato_list_accounts before publishing. Follow completion rules after submitting a post, source, comment, or message. REST JSON bodies and MCP tool arguments have different shapes.
Accounts
For every tool's required and optional argument names, see the MCP input index. The sections below explain behavior and results.
blotato_get_user
Get your account info and verify the connection is working.
Input: none
Output: user ID, email, subscription status
blotato_list_accounts
List all connected social media accounts with subaccounts (for Facebook Pages and LinkedIn Company Pages).
Input:
platform(optional) - filter by platform nameOutput: array of accounts with ID, platform, name, username, and subaccounts
blotato_list_pinterest_boards
List boards owned by a connected Pinterest account. Use this to get the boardId required when publishing a Pinterest pin.
Input:
accountId(required) - Pinterest account ID from blotato_list_accountsOutput: array of boards with
idandname. UseidasboardIdin blotato_create_post.
Credits
blotato_get_credits
Get the account's remaining credits, the account email the API key belongs to, and current pricing (price per 1,000 credits and the min/max purchase quantity). If the user wants more credits, state the returned account email, then direct them to Settings > Billing. Credits are non-transferable between accounts.
Output:
creditsRemaining,accountEmail,purchaseQuantityRange(minandmax), andpricePer1000CreditsUsd.
Publishing
blotato_create_post
Create and publish (or schedule) a post to a social media platform.
Input:
accountId(required) - from blotato_list_accountsplatform(required) - twitter, instagram, facebook, tiktok, linkedin, pinterest, bluesky, threads, or youtubetext(required) - post contentmediaUrls(optional) - array of public media URLsscheduledTime(optional) - ISO 8601 datetimeuseNextFreeSlot(optional) - use next available schedule slotpageId(optional) - for Facebook/LinkedIn pagesmediaType(optional) - for Instagram/Facebook: reel or story. Facebook videos must be"reel"(regular feed videos no longer supported).trial(optional) - for Instagram reels: object withgraduationStrategy("MANUAL"or"SS_PERFORMANCE"). Trial reels are shown to non-followers first.firstComment(optional) - for Facebook/Instagram: text auto-posted as the first comment right after publishing. Not supported for stories. Useful for links.privacyLevel(optional) - for TikTokadditionalPosts(optional) - array of additional posts for threads (Twitter, Bluesky, Threads). Each entry hastextandmediaUrls. The first post uses the top-leveltextandmediaUrlsfields. Blotato handles reply chaining.boardId(optional) - for Pinterest (get from blotato_list_pinterest_boards)title(optional) - for Pinterest or YouTubeprivacyStatus(optional) - for YouTube: public, private, or unlistedplaylistIds(optional) - for YouTube: array of playlist IDs from blotato_list_accounts to add the video to playliststhumbnailUrl(optional) - for YouTube: publicly accessible image URL for a custom thumbnail. Requires a verified YouTube account in good standing
Output: postSubmissionId (poll with blotato_get_post_status)
blotato_get_post_status
Check the status of a submitted post.
Input:
postSubmissionId(required)Output: status, publicUrl (when available on a published result), errorMessage (when failed)
Status values: in-progress -> published | scheduled | failed
in-progress also covers a lookup with no matching result record. It does not validate a guessed ID or confirm a live queue job. Use the original submission ID, keep a polling limit, and follow post lifecycle.
blotato_list_posts
List the user's posts (scheduled, published, and failed) within a time window, ordered by post time (most recent first). Supports cursor-based pagination and optional filters by status and platform.
Each item includes an account field and a state field with a type of scheduled, published (includes postUrl and analytics), or failed (includes errorMessage). account is null when the connected account no longer exists. Published-post analytics are null until metrics have been collected.
Input:
since(optional) - ISO 8601 timestamp. Defaults to 7 days ago.until(optional) - ISO 8601 timestamp. Defaults to 7 days from now.limit(optional) - number of posts per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous responsestatus(optional) - array of statuses to include:scheduled,published,failed. Omit to include all.platform(optional) - array of platforms to include: twitter, instagram, linkedin, facebook, tiktok, pinterest, threads, bluesky, youtube. Omit to include all.
Output: array of posts with
id,postTime,platform,text,mediaUrls,account, and astateobject. A published state includesanalytics.latestandanalytics.history, oranalytics: null. Includescursorfor the next page when more pages are available.
Analytics
blotato_list_top_posts
List your top performing published posts, ranked by an engagement metric over a time range. Use this to answer questions like "what were my best posts last month" or "which posts got the most views".
Each item includes the post content, public URL, platform, publish time, media URLs, the latest analytics snapshot, and the full snapshot history. Analytics are refreshed periodically in the background, so recent posts may have no metrics yet. Metric values are returned as strings because counts can exceed normal number precision.
Input:
since(optional) - ISO 8601 timestamp. Only include posts published on or after this time. Defaults to 30 days ago.until(optional) - ISO 8601 timestamp. Only include posts published on or before this time. Defaults to now.platform(optional) - the MCP tool acceptstwitter,instagram,facebook,threads, orblueskyas an explicit filter. Omit to include all available results. The REST analytics endpoint also accepts TikTok, YouTube, and Pinterest filters. The MCP filter list is narrower than the backend's collection coverage.sortBy(optional) - metric to rank by:likes_count,comments_count,views_count, orreach_count. Defaults toviews_count. For Twitter/X, comments ranking usesreplies_countwhen comments are not reported, and views ranking usesimpressions_countwhen views are not reported.limit(optional) - number of posts to return. Min: 1, Max: 100. Default: 20
Output: array of
items, each withid,content,postUrl,platform,createdAt,mediaUrls,latestMetrics, andmetricsHistory.
blotato_get_post_analytics
Get analytics for a single published post, including the latest metrics and the full snapshot history. This does not trigger a re-fetch; it returns the most recent analytics collected in the background.
Use blotato_list_posts or blotato_list_top_posts to find the published post id first.
Input:
id(required) - published post id from blotato_list_posts or blotato_list_top_postsOutput:
publishedPostId,platform,lastFetchedAt,lastError,metrics(latest, or null when not synced yet), andhistory(array of snapshots, each withfetchedAtandmetrics).
Comments
Read and post comments on your published Instagram and Facebook posts, both audience replies and comments you post through Blotato.
blotato_list_comments
List comments on your published posts, ordered by creation time (most recent first). Supports cursor-based pagination and optional filters.
Each comment includes an isAuthor flag: true for comments you posted, false for audience replies.
Input:
limit(optional) - number of comments per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous responseplatform(optional) - filter by platform:instagramorfacebookaccountId(optional) - filter to a single connected accountparentCommentId(optional) - filter to direct replies to a single commentpostId(optional) - filter to comments on a single Blotato-published post (from blotato_list_posts)since(optional) - only include comments created on or after this ISO 8601 timestampuntil(optional) - only include comments created on or before this ISO 8601 timestamp
Output: array of comments with
id,text,status,isAuthor,platform,postId,parentCommentId,createdAt, anderrorMessage(when failed). Includescursorfor the next page when present.
blotato_get_comment
Get a single comment by its Blotato ID.
Input:
commentId(required) - comment ID from blotato_list_commentsOutput:
id,text,status,isAuthor,platform,postId,createdAt, anderrorMessage(when failed)
blotato_post_comment
Post a comment on one of your published Instagram or Facebook posts, or a reply to an existing top-level comment when you pass parentCommentId. Blotato queues the comment and posts it in the background. To check the status of the comment, poll with blotato_get_comment. Replies to audience comments count toward your monthly active-contacts limit.
Input:
postId(required) - Blotato ID of the published post (from blotato_list_posts)text(required) - comment body. Instagram allows up to 2200 characters, Facebook up to 8000parentCommentId(optional) - Blotato ID of a top-level, posted comment on the same post to reply to. Replies to replies are not supported
Output: the queued comment (poll with blotato_get_comment)
Status values: queued -> processing -> posted | failed
Messages
Read and send direct messages on your Instagram account and Facebook Page. Reply to people who already have a conversation with you.
blotato_list_conversations
List your direct-message conversations, ordered by most recent activity. Supports cursor-based pagination and optional filters.
Input:
limit(optional) - number of conversations per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous responseplatform(optional) - filter by platform:instagramorfacebookaccountId(optional) - filter to a single connected account
Output: array of conversations with
id,platform,participants,updatedAt, andcreatedAt. Includescursorfor the next page when present.
blotato_get_conversation
Get a single conversation by its Blotato ID.
Input:
conversationId(required) - conversation ID from blotato_list_conversationsOutput: conversation object with
id,platform,participants, andupdatedAt
blotato_list_messages
List your messages, ordered by creation time (most recent first). Supports cursor-based pagination and optional filters.
Input:
limit(optional) - number of messages per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous responseconversationId(optional) - filter to a single conversationplatform(optional) - filter by platform:instagramorfacebookaccountId(optional) - filter to a single connected account
Output: array of messages with
id,conversationId,direction,text,payload,status,senderId,recipientId, andcreatedAt.directionisincomingfor messages you receive andoutgoingfor messages you send. Includescursorfor the next page when present.
blotato_get_message
Get a single message by its Blotato ID. Poll this after blotato_send_message to check whether an outgoing message reached sent or failed.
Input:
messageId(required) - message ID from blotato_list_messagesOutput: message object with
id,conversationId,direction,text,payload,status,senderId,recipientId, andcreatedAt
blotato_send_message
Send a direct message to one recipient, or a private reply to a comment. Blotato queues the message and sends it in the background. To check the status, poll with blotato_get_message.
Input:
accountId(required) - connected account to send from (from blotato_list_accounts)platform(required) -instagramorfacebookpageId(required for Facebook) - the Facebook Page to send from (from the account's subaccounts via blotato_list_accounts)recipientId(required) - the other party's id. Use an incoming message'ssenderId(from blotato_list_messages)text(required) - message body. Instagram messages are limited to 1000 bytes, Facebook to 2000 characters. Withbuttonsset, the limit drops to 640 characterscommentId(optional) - to send a private reply to a comment instead of a direct message, pass the comment's Blotato IDbuttons(optional) - Facebook and Instagram only. 1 to 3 call-to-action buttons pinned under the message. See Buttons and Quick RepliesquickReplies(optional) - Facebook and Instagram only. 1 to 13 tappable reply chips. See Buttons and Quick Replies
Output: the queued message (poll with blotato_get_message)
Status values: queued -> processing -> sent | failed
Buttons and Quick Replies
Facebook and Instagram messages may be sent with attached buttons or quick replies via buttons or quickReplies. They are mutually exclusive - pass one or the other, never both.
Buttons sit under the message and stay there. Each has:
type-web_urlopens a link,postbackreports the tap back to youtitle- button label, 1 to 20 charactersurl- required forweb_url, starts withhttps://payload- required forpostback, 1 to 1000 characters
Blotato supports web_url and postback buttons. Phone buttons are not supported.
Instagram renders buttons in the mobile app only. A recipient reading the conversation on instagram.com in a desktop browser sees the message text with no buttons. Pass buttons or a URL inside text, not both, since a message carrying both leaves the URL unclickable on desktop. For a desktop audience, drop buttons and put the URL in text.
Quick replies are tappable chips offered as canned answers. They disappear once the person taps one or types their own message. Each has a title (1 to 20 characters) and a payload (1 to 1000 characters).
Reading a tap. Both kinds of tap arrive as the next incoming message carrying payload.selection, readable with blotato_list_messages. A quick-reply tap sends a real text message, so text holds the chip label. A postback sends no text message: the tap is recorded as an incoming message with text set to the button label. Either way, branch on selection.payload rather than text, since two chips sharing a label are distinguishable only by payload. A web_url button produces no selection.
Reconnect for postback buttons. Blotato subscribes your account to the postback webhook when you connect it. If you connected your account before buttons were launched, reconnect to start receiving postback events. Quick-reply taps need no reconnect.
See Buttons and Quick Replies for the REST equivalent.
Automations
Create and manage DM automations on Instagram and Facebook Pages. An automation sends one direct message when someone comments on your post or sends your account a message. See DM Automations.
An automation sends one message by default. Three optional steps extend it, and Blotato runs them in a fixed order: a follow gate (Instagram only), an email gate, your message, then a webhook.
Every live automation whose trigger matches starts its own run. Two automations matching the same comment both try to answer it, and only one reply reaches the person. Keep one live automation per keyword on each account. Messages without text, such as photos or stickers, never start a run.
Every DM an automation sends counts toward your plan's monthly active-contacts limit. Gate messages go to the same person, so one contact still counts once. See Active Contacts.
blotato_create_automation
Create a DM automation. It starts as an inactive draft unless isActive is true. You can add an email gate, an Instagram follow gate, or a webhook.
Input:
accountId(required) - Instagram or Facebook account from blotato_list_accountsplatform(required) -instagramorfacebookpageId(required for Facebook) - the Facebook Page from the account's subaccountsname(required) - automation label, 1 to 60 characterstriggers(optional) - up to 2 triggers, at most onecomment-receivedand onemessage-received. Each hastype,keywords(omit or empty to match any comment or text message),postId(comment triggers only, the tracked Blotato post ID, not the native platform ID), andisActive(default true). For an externally published Instagram post already tracked through an incoming comment, use the comment's non-nullpostIdafter verifying the account andplatformPostId. OmittingpostIdmatches any post and requires approval for this scope. See post targeting. Any one trigger firing starts a single run. Omittriggersfor a draft with no triggersdmMessage(required) - the message sent when a trigger fires, 1 to 640 charactersbuttons(optional) - up to 3 link buttons, each withtype: "url", atitleof 20 characters or fewer, and aurlfollowGate(optional, Instagram only) -message(1 to 640 characters) andbuttonTitle(20 characters or fewer, defaultI'm following). Holds the DM back until the contact follows the account. Rejected on a Facebook automationemailGate(optional) -message(1 to 640 characters). Holds the DM back until the contact replies with an email address. On automations published after September 14, 2026, a contact with an email already on file skips itwebhook(optional) -method(GET,POST,PUT,PATCH, orDELETE),url(publichttp(s), 2048 characters or fewer), andheaders(optional). Called once the DM sendsisActive(optional) - true publishes it immediately. Default false
Output: the created automation
Follow gate. Blotato sends the gate message with a confirm button, waits up to 30 days for a reply, then reads follower status. A contact who does not follow gets the gate message again. An unknown status sends the DM anyway, since Instagram withholds follower status for a contact who never granted profile access. A confirmed follow is reused for 30 days, but the gate message still goes out on every run.
Any text reply advances the follow gate, so the button tap is a shortcut rather than a requirement. Two setup points to pass on to the user. The Instagram account needs reconnecting if they connected it before DM automations and follow gating landed, since Blotato subscribes to button-tap events at connect time and an older connection does not reliably receive them, leaving runs to expire. Instagram also renders the confirm button in the mobile app only, so write the gate message to ask for a typed reply such as "Reply FOLLOWING once you have" in the message text.
Email gate. Blotato sends the gate message, waits up to 72 hours, and reads the first email address out of the reply. A reply holding no address returns the gate message. A match saves to the contact, then the DM sends. A contact with an email already on file skips the gate, and the DM sends with no gate message. This applies to automations published after September 14, 2026. An automation published earlier asks every time until you pass its current triggers to blotato_update_automation. Use a webhook to export the stored contact email. Conversation and message responses have no dedicated captured-email field, although the original reply remains available as message text.
Webhook. Every method except GET carries a JSON body with two keys, with or without a gate on the automation: {"email": "them@example.com", "isFollower": true}. email is the address on file for the contact, captured by an email gate, and null when Blotato holds none. isFollower is the follower status a follow gate last recorded, and null when Blotato never checked. GET carries no body. The host must resolve to a public address, redirects are not followed, and the timeout is 15 seconds. A non-2xx response or a timeout gets logged and the run still completes, with no retry. A blocked address, a DNS failure, or a connection error fails the run with error code 20304.
blotato_list_automations
List your DM automations, ordered by creation time (most recent first). Supports cursor-based pagination and selected analytics metrics.
Input:
limit(optional) - number of automations per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous response
Output: array of automations with
id,accountId,name,platform,target,triggers(each withid,type,keywords,postId, andisActive),dmMessage,buttons,emailGate,followGate,webhook,isActive,publishedVersionId,createdAt,updatedAt, andstats.statscontainstriggered,completed, andfailedcounts from the last 24 hours pluslastRunAt, which is null when the automation has never run. Archived automations do not appear. Includescursorfor the next page when present.
blotato_update_automation
Update a DM automation. Any of name, triggers, dmMessage, buttons, followGate, emailGate, or webhook you pass replaces that field. Omitted fields stay unchanged. Pass null to remove a gate or a webhook. triggers replaces the whole trigger set, and [] removes every trigger.
Content changes to a live automation publish immediately. Changes to a draft stay saved until you pass isActive true. A live automation needs at least one active trigger, so to clear every trigger pass an empty triggers array and isActive false in the same call. To remove one trigger, pass triggers holding the trigger you keep. To update a single trigger without other changes, use blotato_update_automation_trigger.
Input:
automationId(required) - automation ID from blotato_list_automationsname(optional) - new automation label, 1 to 60 characterstriggers(optional) - replaces every trigger. Up to 2, at most one per type.[]removes alldmMessage(optional) - replaces the message textbuttons(optional) - replaces the link buttons.[]removes allfollowGate(optional, Instagram only) - replaces the follow gate. Pass null to remove itemailGate(optional) - replaces the email gate. Pass null to remove itwebhook(optional) - replaces the webhook. Pass null to remove itisActive(optional) - true publishes, false moves to draft. Omit to keep the current state
Output: the updated automation
blotato_update_automation_trigger
Update a single trigger on a DM automation, for example to turn it on or off. The change applies immediately on a live automation, with no republish. At least one trigger must stay on while the automation is live. To pause the whole automation, pass isActive false to blotato_update_automation instead.
Trigger IDs change whenever the automation's content or triggers are updated. Read them from blotato_list_automations or from the automation blotato_update_automation returns.
Input:
automationId(required) - automation ID from blotato_list_automationstriggerId(required) - trigger ID from the automation'striggersisActive(required) - true turns the trigger on, false turns it off
Output: the updated trigger
blotato_delete_automation
Archive a DM automation and stop new runs. Existing runs, including waiting gates, remain able to continue. Archiving does not cancel messages already queued. Archive only when requested. The archived automation no longer appears in blotato_list_automations.
Input:
automationId(required) - automation ID from blotato_list_automationsOutput: the archived automation
blotato_list_automation_runs
List the execution runs of one automation, ordered by start time (most recent first). A run is one execution: one comment or message matched a trigger. Use it to check whether an automation fires and why a reply did not go out.
Input:
automationId(required) - automation ID from blotato_list_automationslimit(optional) - number of runs per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous responsestatus(optional) - array of statuses to include:running,waiting,completed,expired,superseded,failed. Omit to include allsince(optional) - ISO 8601 timestamp. Only runs with activity at or after this time are returned
Output: array of runs with
id,contactId,platform,status,error(when failed),createdAt, andupdatedAt. A failed run'serrorincludescode,message, and, when available,actionanddetailswith recovery contextStatus values: running, waiting, completed, expired, superseded, failed. A run expires when the contact never answers a gate inside its window: 30 days for a follow gate, 72 hours for an email gate. A run also expires when its message never settles within 30 minutes. A run is superseded when a newer run starts waiting on the same contact
blotato_list_automation_logs
List the execution logs written as an automation's runs advance, ordered by creation time (most recent first).
Input:
automationId(required) - automation ID from blotato_list_automationsflowRunId(optional) - filter to a single run, from blotato_list_automation_runslimit(optional) - number of logs per page. Min: 1, Max: 250. Default: 50cursor(optional) - pagination cursor from a previous response
Output: array of logs with
id,flowRunId,nodeId,level(info,warning,error),message,context, andcreatedAt
blotato_get_automation_analytics
Get analytics for one automation. triggered, completed, and failed are all-time totals. issues counts runs that failed during the last 7 days and is a subset of failed. A run ending on an error after the DM sends counts as failed. Runs still in flight, and runs ending as expired or superseded, count toward triggered but not toward completed or failed.
Input:
automationId(required) - automation ID from blotato_list_automationsOutput:
triggered,completed,failed,issues
Content Extraction
blotato_create_source
Extract content from a URL or text. Polls internally for up to 20 seconds and returns the result directly. If still processing (e.g., a long YouTube video), returns the source ID -- use blotato_get_source_status to poll for completion.
Input:
sourceType(required) - youtube, article, twitter, tiktok, text, audio, pdf, or perplexity-queryurl(optional) - required for URL-based source typestext(optional) - required for text and perplexity-query source typescustomInstructions(optional) - guide extraction (e.g., "focus on key takeaways", "summarize in 5 bullet points")
Output:
idand status. A completed result includestitle,content, andreferenceUrlwhen available. Extraction failure from this create tool is an MCP error containing the source ID.
Long source content ends with [output truncated] when it exceeds the MCP response budget. A completed job does not prove the tool returned the full text. For complete content, use an authorized REST lookup with the same ID. Repeating the MCP status call does not paginate the text. See Extract and repurpose content.
blotato_get_source_status
Check the status of a source extraction. Use this if blotato_create_source timed out and returned an in-progress status.
Input:
id(required) - source ID from blotato_create_sourceOutput:
id, status,titleandcontentwhen completed,messagewhen failed. Completed content is subject to the same truncation behavior as the create tool.Status values: queued -> processing -> completed | failed
An extraction failed result from this status tool is returned in JSON without an MCP isError flag. Inspect status as well as the tool error flag.
Videos and Images
Visual generation through MCP is not supported at this time. Create images, carousels, and videos in the web app or with the REST Create Visual endpoint. Then pass the finished media URLs to blotato_create_post in mediaUrls.
Content Calendar
blotato_list_schedules
List all future scheduled posts, ordered by scheduled time (ascending). Supports cursor-based pagination.
Each schedule includes the draft content (same structure as the post object in blotato_create_post), the scheduled time in UTC, and the target account information.
Input:
limit(optional) - number of schedules per page. Min: 1, Max: 50. Default: 20cursor(optional) - pagination cursor from a previous response
Output: array of schedules with ID, scheduledAt, account info, and draft content. Includes
count(total) andcursor(for next page, if present).
blotato_get_schedule
Get a single scheduled post by ID. Returns the full schedule details including draft content, scheduled time, and account info.
Input:
id(required) - schedule ID from blotato_list_schedulesOutput: schedule object with ID, scheduledAt, account, and draft
blotato_update_schedule
Update a scheduled post's content, scheduled time, or both. At least one field is required.
The scheduled time must be a valid ISO 8601 date string in the future. When the time changes, the post is re-queued for publishing at the new time.
To update the post content, call blotato_get_schedule first, then send the full post as a replacement. accountId, platform, and text are required. Fields you leave out are not kept, and leaving out mediaUrls removes the post's media. Omit post to change only the time.
Input:
id(required) - schedule ID from blotato_list_schedulesscheduledTime(optional) - new ISO 8601 timestamp, must be in the futurepost(optional) - updated post object with accountId, platform, text, mediaUrls, and platform-specific fields
Output: confirmation message
blotato_delete_schedule
Delete a scheduled post and cancel its publishing job. This action cannot be undone.
Input:
id(required) - schedule ID from blotato_list_schedulesOutput: confirmation message
Media
blotato_create_presigned_upload_url
Get a presigned URL to upload a local file directly to Blotato. No intermediate storage (Google Drive, S3) required.
Input:
filename(required) - filename with extension, used to determine content type (e.g., "photo.jpg", "video.mp4")Output:
presignedUrl(URL to PUT the file to, expires after a short period) andpublicUrl(the final public URL to use in blotato_create_post)Max file size: depends on your plan (see Plan Limits)
Rate limit: 120 requests per minute
How to use:
Call
blotato_create_presigned_upload_urlwith your filenamePUT the file contents to the returned
presignedUrlwith the correct Content-Type headerUse the returned
publicUrlin blotato_create_post'smediaUrlsfield
If your media is already at a public URL, you don't need to upload it first -- pass the URL directly into blotato_create_post's mediaUrls field. The presigned upload tool is for local files that don't have a public URL yet.
Accounts and identifiers
Get IDs from Blotato responses. A username, profile URL, or native platform post ID does not replace a Blotato ID.
Select an account
Call
blotato_list_accountsthrough MCP, orGET /v2/users/me/accountsthrough REST.Match the returned platform and account name to the user's intended destination.
Use the returned account
idasaccountId.Select any required Page, board, or playlist from the lookups below.
If several accounts match, ask which account to use. If none match, direct the user to Accounts.
After disconnecting and reconnecting an account, retrieve the current ID before retrying. A saved workflow or brand mapping might contain a stale ID. Confirm the account belongs to the same authenticated Blotato user and platform as the request.
Facebook Page
pageId, required
MCP account subaccounts, or REST GET /v2/users/me/accounts/:accountId/subaccounts
LinkedIn company Page
pageId, required for this destination
MCP account subaccounts, or the REST subaccounts endpoint
LinkedIn personal profile
Omit pageId
Use the LinkedIn accountId
Pinterest board
boardId, required
blotato_list_pinterest_boards, or GET /v2/social/pinterest/boards?accountId=...
YouTube playlist
playlistIds, optional
MCP account subaccounts, or the REST subaccounts endpoint
A returned Facebook Page is a destination to select, not permission to publish to the first Page in the list. LinkedIn Page IDs apply only when the user chooses a company Page. Omitting pageId selects the LinkedIn personal profile, not a company Page. Omit YouTube playlistIds unless playlist placement is requested.
MCP's requiredFields includes hints, not the customer's destination selection. Match the requested Page against subaccounts. An empty subaccount list does not prove the platform account has no Pages, since lookup failures also need investigation. Stop if a required destination ID is unavailable.
Account not found
This error means the submitted ID did not match an account for the authenticated Blotato user and requested platform. It does not establish which value is wrong.
Read the failed request's
accountId,content.platform, andtarget.targetType.Retrieve accounts using the same credential or MCP connection used for publishing.
Select the returned account for the user's intended platform and destination.
Retrieve a separate Page ID when required. Do not put a Page ID in
accountId.Update the saved workflow mapping if it contains an old ID.
Different credentials, an ID from another platform, a Page ID used as an account ID, and an ID saved before reconnection are separate checks. An account dropdown reduces manual copying but does not guarantee a saved selection is current. An AI assistant must perform the lookup rather than assume it happened automatically.
Reconnect only when the connection state or returned error calls for it. If the same ID, platform, and authenticated user still produce the error after a fresh lookup, retain the request details and escalate. Do not assert a key mismatch without checking it. Never include keys or tokens in an escalation.
Before sending another publish request, verify the earlier submission's outcome through Publishing status.
Keep post IDs separate
postSubmissionId from create-post
Poll publishing status with blotato_get_post_status or GET /v2/posts/:postSubmissionId
Published post ID from post listings
Fetch analytics or comments for the published post
Scheduled post id from schedule listings
Get, update, or cancel the scheduled post
Source id
Check source extraction
Visual item.id
Check visual generation
Comment id
Fetch the comment or check reply completion
Conversation or message id
Fetch the corresponding conversation or message
Automation flow and trigger IDs
Manage the automation or a trigger
For blotato_list_posts, inspect each item's state. A scheduled item and a published item describe different records. Read the List Posts response before passing an ID to another operation.
Updating an automation's content or triggers reissues its trigger IDs. Read the returned triggers before updating a trigger. See DM automations.
Full lookup shapes: Accounts, Scheduled posts, Comments, and Messages.
Async jobs and polling
Publishing, source extraction, visual generation, comment posting, and message sending finish after the initial request. Save the returned ID and check the operation's status before reporting success.
Completion rules
Immediate post
blotato_get_post_status or GET /v2/posts/:postSubmissionId
published succeeds. failed stops the workflow. in-progress needs another check.
Scheduled post
Create response, then schedule lookup when needed
Report the returned scheduledTime. scheduled means scheduled, rather than published.
Source
blotato_get_source_status or GET /v2/source-resolutions-v3/:id
completed succeeds. failed stops the workflow. queued and processing need another check.
Visual
GET /v2/videos/creations/:id (REST only)
item.status: done supplies finished media. Stop on item.error, creation-from-template-failed, or insufficient-credits.
Comment
blotato_get_comment or GET /v2/comments/:commentId
posted succeeds. failed stops the workflow.
Message
blotato_get_message or GET /v2/messages/:messageId
sent succeeds. failed stops the workflow.
MCP timing
blotato_create_post waits internally for up to 20 seconds for immediate publishing. blotato_create_source also waits internally for up to 20 seconds. If either returns unfinished work, use its status tool with the same ID.
Wait at least 10 seconds between post or source status calls.
For queued comments and messages, space status checks to stay within the endpoint rate limits.
When the agent's execution window ends, retain the ID and report processing status. Resume with a status lookup rather than another create request.
Inspect both MCP isError and the operation's status. A post or source status lookup returning failed is still a failed job even when the tool call itself succeeded. Source status failures use message. Post status failures use errorMessage.
Post in-progress is a fallback when no matching result record is found, not an independent queue-health check. Verify the saved submission ID and use a bounded polling loop. See post lifecycle.
REST timing
REST create calls return a submission or creation response. The caller manages status checks. Use the intervals above as polling guidance and respect any rate-limit response. Wait at least 15 seconds between visual status calls (GET /v2/videos/creations/:id). A 201 response confirms acceptance, rather than downstream publication.
Visual states
Visual generation uses queueing, generating-script, script-ready, generating-media, media-ready, and exporting before done. Not every template traverses every state.
Inspect item.error on every response. A visual with an error has stopped even if its status remains script-ready or another intermediate state. draft is not a finished rendered visual. Follow Create Visual when choosing render and template inputs.
Use item.mediaUrl or item.imageUrls only after generation succeeds. Those URLs are ready for publishing and do not need a separate upload.
Uploads are a separate flow
A presigned upload response provides 2 URLs. Upload the file bytes to presignedUrl, wait for the upload to succeed, and use publicUrl. There is no upload-status MCP tool. See Media uploads and conversion.
For examples, see Workflow recipes. For failure recovery, see Errors and retries.
Media uploads and conversion
Choose the input flow before publishing. Uploading a file and converting it to meet a platform's requirements are separate operations.
Public image or video URL
Pass it directly in mediaUrls. No upload step required.
Finished Blotato visual
Pass the returned mediaUrl or imageUrls. No upload step required.
File on the user's computer or in the agent's workspace
Complete a presigned upload, then pass publicUrl.
Private download link or editor/share page
Obtain a public downloadable media URL, or upload the file bytes.
Upload a local file
Call
blotato_create_presigned_upload_urlwithfilename, including its extension. For REST, callPOST /v2/media/uploadswith the same field.Send an HTTP
PUTto the returnedpresignedUrl, with the raw file bytes as the request body.After the upload succeeds, pass the returned
publicUrlin the publish request'smediaUrlsarray.
The PUT body is raw bytes. Do not send JSON or multipart form data. The assistant needs access to the file and an HTTP tool or shell to perform the PUT. Creating the URL alone does not upload the file.
If the assistant's environment blocks the upload destination, follow the MCP network-egress troubleshooting. For REST upload shapes, see Upload Media.
Check conversion requirements
Blotato validates media for the destination platform and performs supported conversions when required. Automatic video conversion is limited to videos no longer than 120 seconds. A longer video must already meet the applicable publishing requirements.
The processing queue checks the original file and existing variants. It reuses a valid file without conversion. If none is valid, it either requests a supported conversion of the original or returns the validation error. File upload does not imply every file is converted.
Check the platform media requirements.
Check the file's container, codecs, dimensions, aspect ratio, duration, bitrate, and size.
If a video longer than 120 seconds needs cropping, resizing, or re-encoding, edit and export it before publishing.
Use a URL which serves the media without a login.
Submit the post and check its final publishing status.
An .mp4 filename does not prove the container, codecs, or aspect ratio. Upload success does not establish platform compatibility.
For Instagram Reels, see the Reel troubleshooting checklist. Account upload limits and platform file limits both apply. See Billing and credits and Media requirements.
Container identification errors
Unsupported media format: mov,mp4,m4a,3gp,3g2,mj2 means Blotato did not recognize the file's container brand. The listed formats describe the probe's format family, not the file's exact type. This error is separate from the 120-second conversion limit.
Inspect the file's container metadata, including
major_brand. Do not identify the format from its filename alone.Export the source as MP4 with H.264 video and AAC audio. Renaming the extension does not change the container.
Inspect the exported file and check its dimensions, bitrate, size, and duration against the destination's requirements.
Verify the original submission's status before retrying. If the error persists, provide support with the submission ID and the exported file's metadata. Keep signed URLs and credentials out of support messages.
For the agent: the current parser recognizes MP4 brands isom, iso1 through iso6, mp41, and mp42. It recognizes MOV through the exact padded brand qt . Missing or unrecognized brands produce the format-list error, even for a short video. A recognized container does not prove publishing compatibility.
Post lifecycle
A post moves through submission, processing, and a published or failed outcome. Scheduling adds a wait until the chosen time.
Create response with postSubmissionId
Blotato accepted the request
Save the ID
in-progress
No failed, published, or scheduled result was found
Verify the saved submission ID and poll within a waiting limit
scheduled
The post is scheduled
Report scheduledTime and stop immediate polling
published
Publishing completed
Return publicUrl when supplied
failed
Publishing stopped
Explain errorMessage and resolve the cause
Publish now
Fetch the destination account and required IDs.
Submit the post once.
Follow status polling.
Report the returned outcome.
Publish later
Resolve the user's requested date, time, and timezone.
Submit with a future
scheduledTimeoruseNextFreeSlot: true.Report the resolved UTC time in the user's timezone.
Use scheduled-post management for later edits or cancellation.
Do not keep polling a future scheduled post as if publication should finish now. Check publication after its scheduled time when the task requires it.
Look up existing work
Use List Posts to inspect published, scheduled, and failed records. Its state.type values describe list items, while the submission-status endpoint uses the status values above.
Keep submission, scheduled, and published post IDs separate. A retry after an uncertain network result starts with looking up existing work. Repeating create-post risks a duplicate.
The submission-status endpoint does not verify a live queue job before returning in-progress. This fallback also applies when it finds no record for the supplied ID. Use the ID from the original create response and the original Blotato account credentials. Do not treat an arbitrary ID returning in-progress as evidence of accepted work. For missing or conflicting records, follow Find a post's outcome before retrying.
Scheduling posts
Choose a specific publish time or the next free calendar slot, not both. An explicit scheduledTime does not bypass slot validation if useNextFreeSlot is also true. A scheduled result confirms the queue entry. Check publication after the chosen time if your workflow needs the live post URL.
Choose a time
Resolve the user's date, time, and timezone. Ask for the timezone when it is unknown.
Convert the chosen instant to a future UTC ISO 8601 timestamp, such as
2030-06-15T15:00:00Z. Replace example dates with the intended future date.Set
scheduledTimein the create-post request.Read the returned
scheduledTimeand report it in the user's timezone.
For MCP, scheduledTime is a tool argument. For REST, it is a top-level sibling of post:
The API parses and returns scheduled times in UTC. There is no separate timezone field in this create-post request. The web calendar's timezone setting controls the calendar experience.
Use the next free slot
Set up the calendar's schedule slots.
Set
useNextFreeSlot: truein place of a specificscheduledTime.Report the resolved time returned by Blotato.
If no matching slot or available time is found, post creation returns a validation error. Add or correct slots for the intended platform, account, and Page. Do not retry without scheduling fields unless the user authorizes immediate publishing.
In REST, useNextFreeSlot is a top-level sibling of post. For slot definitions and advanced REST scheduling, see Weekly posting schedule and Publish Post.
Edit or cancel a scheduled post
List schedules with
blotato_list_schedulesorGET /v2/schedules.Read the selected scheduled post with
blotato_get_scheduleorGET /v2/schedules/:id.Update it with
blotato_update_scheduleorPATCH /v2/schedules/:id, or cancel it withblotato_delete_scheduleorDELETE /v2/schedules/:id.Check the returned state or re-read the schedule to verify the change.
Use the scheduled post's ID from the schedule listing. See Scheduled Posts for update fields and preserved content.
API rate limits
Blotato applies route-specific request limits. These limits are separate from subscription limits, credits, and social platform publishing limits.
Create post
30
List posts or get post submission status
60 for each route
Get post analytics
60
Upload media from a URL with POST /v2/media
30
Create a presigned upload URL
120
List Pinterest boards
45
List comments or get a comment
60 for each route
Post a comment
30
List conversations, get a conversation, list messages, or get a message
60 for each route
Send a message
30
List or get DM automations, runs, logs, or analytics
60 for each route
Create, update, delete an automation, or update a trigger
30 for each route
This table covers the listed routes. Consult each endpoint's reference for other limits. MCP tools call the underlying REST routes, so status polling and tool sequences consume requests too.
Handle a limit response
Stop requests to the limited route after
429.Wait for the retry interval when the response supplies one.
Reduce concurrency and request frequency before resuming.
Use polling intervals rather than repeated status calls without a delay.
A platform publishing restriction is a different limit. For example, the Starter plan's TikTok restriction counts 3 distinct TikTok accounts posted to during a rolling 24-hour window. It is not an API request-per-minute limit or a count of connected accounts. See TikTok limitations.
For credit purchases, see the limits in Buy Credits.
Errors and retries
Read the returned error before changing the request. For REST requests, record the HTTP status and response body. For MCP, inspect the tool result and its isError flag. A request accepted by Blotato still needs its workflow's completion check.
For customer support, use Diagnose and answer to preserve the client, failing stage, previous attempts, and human corrections. Do not repeat a setup question already answered in the conversation.
For missing, delayed, or duplicate posts, follow Find a post's outcome before retrying. An HTTP status or an inaccessible platform URL alone does not establish the underlying cause.
401, invalid API key, or invalid session
Follow authentication checks
Subscription-related 403
Check Billing
404
Re-fetch the record and verify the ID type and account
Validation error, often 422
Correct the named field using the endpoint schema
429
Wait for the retry interval if provided, then reduce request frequency
Network error or 5xx on a read
Retry with a delay and a bounded attempt count
Network error after a create request
Check existing work before submitting again
Post status failed
Read errorMessage and the platform requirements
Visual response contains item.error
Stop polling and explain the generation error
Empty analytics or inbox result
Check the feature's sync timing and supported platforms or inbox setup
Media fetch or conversion failure
Follow the media checklist
Inspect a failed request
Open the Logs.
Select the request.
Read its payload, response, and error message.
Correct the cause before resubmitting.
For n8n requests, the dashboard's FIX MY AUTOMATION action helps repair the workflow. See the n8n walkthrough. This action is specific to n8n.
Retry without duplicating work
Save every submission or creation ID returned by a successful create request.
If a status call fails, retry the status call with the saved ID.
If creation timed out without an ID, inspect the dashboard and existing posts or schedules before creating another item.
For a failed post, correct the error before a new submission. An unchanged retry often fails for the same reason.
Set an attempt or elapsed-time limit in your automation. Report unfinished work and its ID when the limit is reached.
Blotato does not expose a documented client-supplied idempotency header for create-post requests. Internal duplicate detection is not a guarantee for arbitrary changed payloads, times, or retries. Retain the submission ID, inspect existing work, and do not invent an idempotency header.
See Error reference, API FAQs, MCP FAQs, and Get support for specific cases.
Diagnose and answer a support question
Scope: support agents answering questions about the website, MCP, REST, n8n, or Make. Customer assistants use the same checks before retrying a failed operation.
Response contract
Answer the question using the context already supplied.
Give the next supported action for the customer's surface.
State what proves success or what remains unresolved.
Link the relevant section. A tutorial supplements the answer, not replaces it.
Do not ask a basic setup question again when the customer already answered it. Preserve the exact error, attempted steps, and human support corrections. A historical incident or an empty result does not prove a current outage.
Identify the stage
“Connected”, but no tools
Identify the client. Separate connector creation, authorization, callback, and tool discovery. Use client setup.
A successful account-list call verifies authentication. A redirect alone does not.
API key rejected
Check the provider, endpoint, header, full key, and paid-access state using authentication checks. Never request the secret in chat.
Stop repeated writes. Record the sanitized error and HTTP status.
Account not found, wrong account, or reconnected account
Re-list accounts and match platform, name, and destination. Retrieve Page or board IDs where required. See identifier rules.
No unambiguous matching destination means no publishing action.
“Upload failed”
Identify whether the artifact is workflow JSON or media. For media, distinguish local bytes, signed upload, Blotato fetching a host, and platform validation.
Use media diagnosis, not a generic reconnect instruction.
“Automatic upload isn't possible” or “no media library”
Separate reusable web-app storage from API/MCP uploads. Identify the client's file access and HTTP upload capability. Use the local media upload and client setup guides.
The absence of a reusable media library does not block automated upload or publishing. Do not substitute generated visuals when the customer asks to post existing files.
Accepted request, but nothing published
Retrieve the saved submission ID with post status. Inspect status and error fields. For missing or conflicting records, use publishing-status diagnosis.
Scheduled is not published. Unknown outcome is not permission to create again. in-progress alone does not prove a live queue job.
Generation failed despite credits
Inspect the visual's error and template inputs. Check complete-job cost, not only a per-scene price.
Use visual failure diagnosis. Do not infer the cause from a terminal status alone.
Missing post drafts
Use draft-finding steps. Apply the same-browser limitation only after confirming an AI Agent draft and a device or browser change. An empty AI Agent list does not prove the draft is lost.
Edit, mute, download, or post an existing video
Open the existing visual. Distinguish track audio, caption narration, preview state, export, and post draft.
Use Edit, mute, and export. Create Post is not publication. Do not regenerate to solve a download question.
Empty analytics or inbox
Check the operation's platform support, permissions, post eligibility, and collection timing.
Cancellation, refund, discount, or paid-but-inactive
Separate published policy from the customer's verified subscription and payment state.
Use billing policy. Account changes need authorized execution and a confirmed result.
Media upload and conversion
Scope: existing image or video files, not n8n workflow JSON or generated-template records.
Identify where the file exists: the customer's device, the assistant's workspace, or a remote URL.
For local media, verify the assistant has file access and an HTTP upload tool. A presigned URL alone does not upload bytes.
For a client sandbox error, inspect the blocked host and client policy. Do not apply client allowlist instructions to a remote host rejecting Blotato's servers.
For remote media, verify a direct file response without interactive login. Browser access alone does not prove server-to-server access.
Inspect the actual container, codecs, file size, duration, and dimensions. An
.mp4extension is not a metadata probe.Apply conversion and platform requirements. A video longer than 120 seconds is not automatically prohibited, but must already satisfy the destination's requirements.
After correction, verify the publishing result. Upload success does not prove publication.
Repeated failure or unclear cause
Carry forward completed checks and their results. Do not resend the same checklist without new evidence.
Record the client or integration, operation, destination platform, timestamp and timezone, request/submission/visual ID, exact error, and sanitized request shape.
Record expected versus observed behavior and attempted fixes.
Stop if the next action risks another charge, duplicate post, wrong destination, or unauthorized account change.
Use Get support with the evidence. Do not include API keys, OAuth codes, signed upload URLs, or unrelated customer data.
For a capability question with a confirmed answer, answer it directly. For example, Facebook publishing targets a Page, not a personal profile. Do not send setup tutorials or ask the customer to reconnect for an unsupported destination.
This page does not change support-ticket closure rules or grant tools permission to modify accounts.
Find a post's outcome before retrying
Use this page when a post disappears from Upcoming Posts, remains in progress, shows published without a visible post, or appears twice. These symptoms do not establish the cause.
Using the Blotato website
Record the intended social account or Page, content, and submission or scheduled time with timezone.
Open any returned platform URL and check the intended account on the platform.
Read the exact error before changing media, reconnecting an account, or retrying.
If those records do not establish the result, contact support with the evidence below. Do not submit a replacement while the original outcome is unknown.
Using MCP, REST, n8n, or Make.com
Retrieve the
postSubmissionIdfrom the original create response. Do not substitute a schedule ID, published-post ID, or guessed UUID.Call
blotato_get_post_statusor Get Post Status with that ID and the original Blotato account credentials.Follow the status-specific completion rules.
Inspect existing posts and schedules when the submission result is missing or inconsistent.
Retain the ID when your polling limit is reached. Escalate the unresolved result instead of repeating create-post.
The status endpoint returns in-progress when no matching failed, published, or scheduled record is found. It does not independently confirm a live queue job. A wrong or unavailable submission ID is not proven valid by this status. Verify the original create response before further polling.
Interpret the evidence
Schedule disappeared at its due time
The schedule is no longer in that list. Check publishing results before assuming failure or success.
Published record, but platform URL is absent or inaccessible
Blotato recorded publication. Check the destination and platform account. An inaccessible URL alone does not prove moderation, deletion, or suppression.
Failed result
Read the error and check the destination before retrying. Correct an identified validation or connection problem. Retry a temporary failure only after checking for an existing post.
2 copies on the platform
Record both URLs and submission times. Do not infer a timeout or blame a particular client without request evidence. Ask which copy to keep before removing content through the platform.
Several accounts fail at once
Investigate a shared service or incident. This pattern alone is not proof of an outage or its owner.
Escalation evidence
Include the client, destination, exact error, timestamps with timezone, postSubmissionId when available, relevant request/reference IDs, and platform URLs. State which checks are already complete. Switch to Developer Platform and open Logs for recorded activity. Filter by Posts, Videos, Media, Accounts, or DM, then Processing, Failed, or Success. Search or filter by platform and account. Absence from a filtered log list does not prove no publishing attempt occurred.
Do not share API keys, OAuth codes, or signed upload URLs. Do not promise incident compensation or report a refund, credit adjustment, deletion, or reconnection as completed without confirmation.
Publish and verify a post
Scope: external assistants using MCP or REST, including n8n and Make HTTP requests. Publishing requires paid access, a connected social account, and the user's authorization for the content and destination. For website actions, use Create posts.
Prompt for your assistant:
Publish this post to my selected Blotato account. First list my accounts and confirm the destination from my request. Check the platform requirements, submit the post, and return its final status and public URL.
Using MCP
The following text-only X example illustrates the complete path. Replace example IDs and text with the customer's requested destination and approved content. Other platforms have different requirements.
Call
blotato_list_accountswith{"platform":"twitter"}. The result is an account array, not REST'sitemswrapper:
Match the requested account. An empty list confirms authentication but requires connecting an account in Accounts. Multiple matching destinations require clarification before a write.
Call
blotato_create_post:
Read the tool result, including
isError,status, and any error text. If processing continues, retainpostSubmissionIdand callblotato_get_post_statusat least 10 seconds later:
Follow the result table below. The create tool waits internally for up to 20 seconds. It might return a completed result without another status request. Do not submit the same post again to check progress.
Adapt the destination
Call
blotato_list_accountsto findaccountIdand any Page IDs.Read the destination's platform guide. For Pinterest, call
blotato_list_pinterest_boardsto getboardId.Supply public media URLs, or complete the local upload.
Call
blotato_create_postwith the account, platform, content, and required platform fields.If the returned status is
in-progress, callblotato_get_post_statuswith the returnedpostSubmissionId, waiting at least 10 seconds between checks.Return
publishedand the suppliedpublicUrl, or explainfailedand itserrorMessage.
The create tool waits internally for up to 20 seconds. Another create call starts another submission. Continue unfinished work with the status tool.
Using REST
Fetch
GET /v2/users/me/accountsand any required subaccounts or Pinterest boards.Send
POST /v2/postsusing the Publish Post schema.Save
postSubmissionIdfrom the response.Poll
GET /v2/posts/:postSubmissionIdaccording to the completion rules.
Set post.content.platform and post.target.targetType to the same platform. Each create request has one account and destination.
Complete REST example
Send
GET https://backend.blotato.com/v2/users/me/accounts?platform=twitterwith theblotato-api-keyheader. Select the matchingitems[].idasaccountId.Send this body to
POST https://backend.blotato.com/v2/postswith the same auth header andContent-Type: application/json:
Save the accepted response's
postSubmissionId:
Send
GET https://backend.blotato.com/v2/posts/a1b2c3d4-e5f6-7890-abcd-ef1234567890with the auth header. Use the ID from step 3, not the example ID. Wait at least 10 seconds between status requests.
Completion and recovery
The status endpoint returns the same state vocabulary used by the MCP status tool:
published
Report success and the returned publicUrl when supplied. Do not construct a guessed URL.
failed
Stop. Read errorMessage, correct the cause, and obtain authorization for any new submission outside the original request.
in-progress
Poll the saved ID with a waiting limit. Report the ID and unresolved state if the limit is reached.
scheduled
Report the returned scheduledTime. Do not describe it as published.
No response or an uncertain write
Inspect the Logs and existing work before creating again.
For media, complete upload and validation before creating the post. For Instagram, Facebook, TikTok, Pinterest, YouTube, or LinkedIn, use the platform-specific request, including required media and destination fields.
Cross-post
Select the accounts requested by the user.
Adapt the media and target fields for each platform.
Create a separate submission for each destination.
Track each submission ID and report each outcome separately.
A success on one platform does not establish success on another. For publishing later, use Scheduling.
Schedule and manage posts
Prompt for your assistant:
Schedule this post for the date, time, and timezone I specify. Use my selected account, then show the resolved publish time. If I ask to change a scheduled post, find and update the existing schedule.
Create a schedule
Call
blotato_list_accountsand select the destination.Resolve the requested date and timezone, or choose the next free slot.
Call
blotato_create_postwithscheduledTimeoruseNextFreeSlot: true.Verify the resolved
scheduledTimeand report it in the user's timezone. If no time is returned, retrieve status using the savedpostSubmissionIdbefore promising a schedule.
For REST, use POST /v2/posts with scheduling fields beside post. Follow Scheduling posts for the request layout and UTC rules.
Request and verification example
Use an authenticated connection. For “June 15, 2030 at 9 AM in America/Denver,” the resolved UTC time is 2030-06-15T15:00:00Z. Replace this example with the user's intended future date, accounting for daylight saving time on that date. Replace accountId with the selected Twitter/X account from lookup.
Call blotato_create_post once:
For REST, send this body to POST https://backend.blotato.com/v2/posts with blotato-api-key: YOUR_API_KEY and Content-Type: application/json:
Save the returned postSubmissionId. A REST acceptance response has this shape:
If further verification is needed, call blotato_get_post_status with {"postSubmissionId": "RETURNED_ID"}, or request GET /v2/posts/RETURNED_ID with the authentication header. A scheduled result has this shape:
Report “Scheduled for June 15 at 9 AM America/Denver,” not “Published.” For an unfinished result, wait at least 10 seconds between status checks and stop after a client wait budget, such as 2 minutes, with the saved ID and unresolved state. An uncertain result is not permission to create another post.
Change or cancel
Call
blotato_list_schedulesto locate the scheduled item.Call
blotato_get_scheduleto read its content and time.Call
blotato_update_schedulewith the intended change, orblotato_delete_scheduleto cancel.Verify and report the resulting schedule state.
For REST, use the corresponding GET, PATCH, or DELETE /v2/schedules/:id operation. See Scheduled Posts.
Scheduled-post IDs differ from submission and published-post IDs. Obtain the schedule ID from the listing. A scheduled result is the stopping point for this task. Publishing verification belongs after the scheduled time.
Stop conditions and batches
Do not assume the create response has status: "scheduled". A returned submission ID or a successful HTTP response alone does not establish the resolved schedule. Use the scheduling rules and post status.
Before useNextFreeSlot, verify slots exist for the intended destination. If no matching slot or available slot time is found, post creation returns a validation error. Do not remove the scheduling field and retry, since a request without scheduling publishes immediately.
For a batch, record each destination, resolved time, submission ID, schedule ID when available, and outcome. Retry only a confirmed failed item after correcting its cause. Do not recreate successful items because another item failed. Scheduling a set of posts does not create a recurring content-generation automation.
Upload local media
Scope: an existing image or video file. This is not the import flow for an n8n workflow template and does not create a generated Visual in the Videos library.
Prompt for your assistant:
Upload this file to Blotato using a presigned upload URL. Send the raw bytes with HTTP PUT, confirm upload success, and use the returned public URL for my post.
Ensure the assistant has access to the file in its workspace.
Call
blotato_create_presigned_upload_urlwith the filename and extension.Upload the bytes to
presignedUrlwith an HTTP PUT.Use
publicUrlinblotato_create_postafter the upload succeeds.Follow publishing verification.
For REST, create the upload URLs with POST /v2/media/uploads. The upload itself goes to the returned signed URL, rather than to the REST API endpoint.
Request and result
Call blotato_create_presigned_upload_url with this argument, or send it as JSON to POST https://backend.blotato.com/v2/media/uploads with the blotato-api-key header:
The response contains presignedUrl and publicUrl. Preserve the returned values. Do not derive one URL from the other or share the signed URL in a support reply.
Send
PUTtopresignedUrlwith the raw file bytes. Do not use JSON or multipart form data.Check the upload response for success before using
publicUrl.Confirm the file meets the plan and platform limits.
Pass
publicUrlin the publish request'smediaUrlsarray.Verify the submission's final state separately.
If the client blocks the upload host, resolve the client permission or use a supported environment. If Blotato cannot fetch a remote source, inspect the source host's response instead. These are different request directions. See stage-based diagnosis.
If the file already has a public download URL, pass it directly in mediaUrls. No upload step required. If the assistant lacks file or HTTP access, use a client with those capabilities or provide a public media URL.
See Media uploads and conversion, Upload Media reference, and MCP upload troubleshooting.
Create and publish a visual
Scope: REST API visual generation, including n8n and Make. Visual generation through MCP is not supported at this time. The in-app AI Agent's video restriction is not a restriction on this workflow. Generation consumes credits according to the requested job. Confirm authorization before starting a new paid attempt.
Prompt for your assistant:
Find a Blotato template for the image, carousel, or video I describe. Read its inputs, generate the visual, and check its status until it finishes or returns an error. Show me the finished media before following my publishing instructions.
Using the Blotato API
Call
GET /v2/videos/templatesto select a template and inspect its inputs.Call
POST /v2/videos/from-templateswithtemplateId, template-specificinputs, a prompt when needed, andrender: truefor rendered output.
Use the exact template ID returned by the listing. Do not strip a path ID to its UUID. Request fields=id,name,description,inputs when you need the template name and input schema.
Save the returned
item.id.Call
GET /v2/videos/creations/:idat least 15 seconds apart.Stop when
item.statusisdone, or whenitem.erroror a failure state appears.Use the returned
item.mediaUrloritem.imageUrlsfor the publish workflow.
Do not invent template input fields. Use the template's current schema. Inspect inputs without generating instead of running a blank generation request. Generated media URLs do not need another upload. The completed visual has not been posted to a social platform until the publish workflow succeeds.
See Create Visual, Get Visual Status, and the template catalog.
Request and output example
Retrieve templates and inspect the current inputs. The following quote-card template is an example, not a substitute for choosing the customer's requested output. Keep the complete template ID.
Send this body to
POST https://backend.blotato.com/v2/videos/from-templateswithContent-Type: application/jsonand theblotato-api-keyheader:
Save
item.idfrom the response. Aqueueingstatus means accepted, not finished:
Call
GET /v2/videos/creations/a1b2c3d4-e5f6-7890-abcd-ef1234567890. Substitute the saved ID and wait at least 15 seconds between checks.On
done, read the returneditem.imageUrlsfor image outputs oritem.mediaUrlfor video. Do not guess the URL or reuse the source input as the generated result.Stop on
item.error,creation-from-template-failed, orinsufficient-credits. A draft orscript-readyrecord without completed media is not ready to publish. Inspect visual status for next steps.Review the output before a separate publish request. Use the returned URLs directly without another upload.
Set a waiting limit. If generation remains unfinished, return its ID and current state. Do not create another paid job because a status request failed or time elapsed. For a brand requirement, follow Brand Kit for the REST brand fields.
Using Blotato Web App
Follow Make your first AI video to choose a template and generate a visual.
Review the finished output.
Follow the recommended workflow to publish it.
For images, see AI Images. For credit questions, see Video FAQs.
Extract and repurpose content
Prompt for your assistant:
Extract the content from this source with Blotato, then adapt it for the social platforms I choose. If a platform needs media, use media I supply or generate a visual before publishing.
Before starting
Use an authenticated connection. Choose sourceType explicitly. Use text for text or perplexity-query, and url for article, YouTube, Twitter/X, TikTok, audio, or PDF sources. A URL alone does not choose the source type.
MCP example
Call
blotato_create_sourcewith the user's source. This example uses supplied text and requires no external source URL.
Save the returned
id. The tool waits internally for up to 20 seconds. If the result is stillqueuedorprocessing, callblotato_get_source_statuswith this shape, replacing the example ID.
REST equivalent
Send the following body to POST https://backend.blotato.com/v2/source-resolutions-v3 with blotato-api-key: YOUR_API_KEY and Content-Type: application/json. REST nests the source fields. MCP does not.
A 201 response contains the job ID, not extracted content:
Read GET /v2/source-resolutions-v3/123e4567-e89b-12d3-a456-426614174000 with the same authentication header. A completed response has this shape. The title and content below are illustrative, not guaranteed output text.
Completion and recovery
Wait at least 10 seconds between status requests for an unfinished job. Use a bounded wait, such as 2 minutes, then report the saved ID and pending state. This is a client wait budget, not a service completion promise.
On
completed, use the returnedcontentandtitle. Do not treat an accepted ID as extracted content. If MCP content ends with[output truncated], it is not the full extraction. Use the REST lookup with the same ID when your client has an authorized API connection, or disclose the incomplete content. Repeated MCP lookups do not paginate the text.On REST or MCP status lookup
failed, inspectmessage. The MCP create tool reports extraction failure throughisErrorwith the source ID, while the status tool returns afailedstatus in its JSON result. Check both the tool error flag and the operation status. Correct the source or access problem before another extraction attempt.After a timeout, look up the saved ID instead of submitting another extraction. If no ID was received, report the uncertain outcome before retrying.
Adapt the content to the user's request. Stop after returning the content for an extraction-only request. For publication, use existing media, or omit media for text-only posts supported by the selected platform. Create a visual only when new media is requested. Follow Publish and verify with the user's publication approval.
Extraction produces source content. It does not itself download a reusable social video or publish a post. An Instagram caption without an image or video is insufficient for publishing.
See Create Source and Get Source for source-specific requirements and errors.
Read post analytics
Prompt for your assistant:
Compare my posts for the period I specify. Use Blotato's returned metrics and snapshot dates. Identify missing metrics and explain refresh timing before drawing conclusions.
Select the posts
Use an authenticated connection. Resolve the user's date range and timezone before requesting a ranking. since and until filter publication dates, not the dates on which engagement occurred. These results are not a daily engagement breakdown.
Call blotato_list_top_posts with a supported ranking metric. This example requests up to 10 Instagram posts published in the specified UTC interval:
For REST, request GET https://backend.blotato.com/v2/analytics with these fields as URL-encoded query parameters and blotato-api-key: YOUR_API_KEY. Read items from the result. An empty list does not establish 0 engagement. Check date filters, platform coverage, and plan access.
Inspect a post
Use blotato_list_posts to locate a specific post, or select a published post from the ranking. Call blotato_get_post_analytics with its published post ID:
For REST, request GET /v2/posts/123e4567-e89b-12d3-a456-426614174000/analytics with the authentication header. This id is not postSubmissionId.
Read metrics, lastFetchedAt, lastError, and history. Each history entry has fetchedAt and metrics. Metric counts are returned as strings. Response metric names such as viewsCount differ from ranking keys such as views_count. Preserve numeric precision when comparing large counts.
Completion and missing data
Report the returned metric values and snapshot times. Different collection times affect comparisons.
Treat missing or null metrics as unavailable, not 0. If the response is an error, preserve its message instead of manufacturing an empty result.
For
404, distinguish a missing published post, unavailable plan access, and analytics not yet synced using the returned error. Do not retry post creation to obtain analytics.Check the post's platform, eligibility, and publication time against refresh checkpoints. Reading analytics returns stored snapshots. It does not trigger collection.
Stop after reporting the available evidence and next checkpoint or unresolved error. Repeated immediate reads do not force a refresh. A new connection does not promise historical backfill. Follow pending-data diagnosis before recommending reconnection.
Read the API reference and metrics reference before promising a metric or refresh interval. Platform, plan, and interface coverage differ.
Read and reply to comments
Blotato's comments API and MCP tools support Instagram and Facebook.
Prompt for your assistant:
Find comments on the posts I select, summarize them, and draft replies. When I ask you to send a reply, post it and verify its final status.
Find the post and comment
Use an authenticated connection and an Instagram or Facebook account with comments enabled and the required permissions.
Call
blotato_list_poststo find the selected published post's Blotato ID.Call
blotato_list_commentswith the following shape. Replace the examplepostIdwith the returned ID.
Read
items. If acursoris returned and more results are needed, pass it with the same filters in the next call. A missing cursor marks the end.Select the intended comment. A reply's parent must be a top-level comment with
status: "posted"on the same post. Replies to replies are not supported.
Send an approved reply
Call blotato_post_comment once with the user's approved text and IDs from the lookup:
Omit parentCommentId only when the user requested a new top-level comment. Do not omit it to bypass a reply error.
Save the returned comment id. Call blotato_get_comment with:
For REST, use GET https://backend.blotato.com/v2/comments?postId=PUBLISHED_POST_ID&limit=50, POST /v2/comments with the same reply JSON, and GET /v2/comments/RETURNED_COMMENT_ID. Include blotato-api-key: YOUR_API_KEY on every request and Content-Type: application/json on POST. URL-encode query values.
Completion and recovery
posted
Report the reply as posted.
queued or processing
Read the same comment again. Do not send another reply.
failed
Stop and inspect errorCode and errorMessage.
deleted
Report the deleted state. Do not replace the comment without the user's request.
Use a client polling budget, such as 10-second intervals for up to 2 minutes. This is not a delivery-time guarantee. If still pending, retain the ID and report the pending state. After a send timeout with no ID, inspect recent comments before considering another write. If the outcome remains uncertain, stop rather than risk a duplicate reply.
Read Comments for plan access, retention, and platform restrictions.
An empty inbox after connecting is a sync question. Follow Inbox setup and timing before concluding the account has no comments.
Read and reply to messages
Blotato's messaging API and MCP tools support Instagram and Facebook. Replies are subject to the platform's messaging rules and windows.
Prompt for your assistant:
Find the conversation I specify, read its recent messages, and draft a reply. When I ask you to send it, use the existing recipient identifiers and verify the send status.
Find the recipient
Use an authenticated connection and confirm messaging permissions and the platform messaging window.
Call
blotato_list_conversations, filtering by the intended account and platform. Select the conversation fromitems. Follow returned cursors until the requested conversation is found or the results end.
Call
blotato_list_messageswith the selected conversation'sid. Replace all example IDs with returned values.
Read
directionbefore selecting the reply recipient. For anincomingmessage, the other participant issenderId. For anoutgoingmessage, the other participant isrecipientId. Use the conversation'saccountIdas the sending Blotato account. Do not invent a recipient ID from a username or send to the connected account itself.
Send an approved reply
For this Instagram example, assume the selected incoming message's senderId is 1784000000. After the user approves the reply, call blotato_send_message once:
For REST, send the following JSON to POST https://backend.blotato.com/v2/messages with blotato-api-key: YOUR_API_KEY and Content-Type: application/json. REST uses target, not MCP's top-level platform.
For Facebook, select the Page from account lookup and supply MCP pageId or REST target.pageId with the Facebook platform value. Do not reuse the Instagram target or select the first Page without matching the user's request.
REST lookups use GET /v2/conversations?accountId=ACCOUNT_ID&platform=instagram&limit=50 and GET /v2/messages?conversationId=CONVERSATION_ID&limit=50. Use the authentication header and URL-encode query values.
Verify the send
Save the returned message id. The initial queued state is not confirmation of delivery. Call blotato_get_message with:
For REST, read GET /v2/messages/RETURNED_MESSAGE_ID with the authentication header.
On outgoing
sent, report the message as sent. This does not establish the recipient read it.On
failed, stop and preserveerrorCodeanderrorMessage. Resolve permissions, messaging-window, recipient, or account errors before another attempt.For
queuedorprocessing, read the same ID within a bounded client wait, such as 10-second intervals for up to 2 minutes. If still pending, report the saved ID and state. This budget is not a delivery promise.After a send timeout, inspect the saved message or recent conversation messages. Do not resend while the first attempt's outcome remains uncertain.
For buttons, quick replies, and comment-to-DM behavior, read the Messages reference before choosing a message shape. For connection and history questions, see Inbox setup.
Manage DM automations
Use DM automations for supported Instagram and Facebook comment or message triggers. Read the DM Automations guide for trigger behavior, limits, gates, and platform restrictions.
Prompt for your assistant:
Set up a Blotato DM automation for the account, trigger, and reply I describe. Review the trigger and reply with me, then apply my requested activation state. Show how I will check its runs and errors.
Call
blotato_list_accountsto identify the account.Call
blotato_list_automationsto inspect existing flows before creating a duplicate.Read the automation schema and match the trigger and message to the user's request.
Call
blotato_create_automationorblotato_update_automationfor the requested flow.Inspect the returned flow and activation state.
Use
blotato_list_automation_runs,blotato_list_automation_logs, andblotato_get_automation_analyticsto inspect results.
Create an inactive Instagram example
Use an authenticated connection and the account ID from lookup. This example responds to incoming messages matching the keyword workshop. It does not schedule social posts or generate content on a timer.
Call blotato_create_automation after checking existing automations and confirming the trigger and reply with the user:
The trigger is enabled within the draft, but the flow remains inactive because isActive at the top level is false. Read automation.id, automation.isActive, and automation.triggers from the MCP result. Creating a draft is not activation.
For REST, send this JSON to POST https://backend.blotato.com/v2/dm-automations with blotato-api-key: YOUR_API_KEY and Content-Type: application/json:
The REST result wraps the saved record in flow, not MCP's automation. Save flow.id. Read it later with GET /v2/dm-automations/RETURNED_FLOW_ID and the authentication header. For Facebook, set the Facebook platform and target and include the selected Page ID. See the automation schema.
Activate and verify
If the user requests activation, call blotato_update_automation with the saved flow ID:
For REST, send this body to PATCH /v2/dm-automations/RETURNED_FLOW_ID. REST requires the patch wrapper, unlike the MCP tool arguments:
Verify the returned activation state. Changes to an already active flow take effect immediately. Do not treat a content update to a live flow as an unpublished draft.
For an authorized test, send the matching message from a different account. Messages sent by the connected account do not start the run. Read the resulting runs with:
For REST, use GET /v2/dm-automations/RETURNED_FLOW_ID/runs?limit=20. Inspect a selected run's logs with blotato_list_automation_logs or GET /v2/dm-automations/RETURNED_FLOW_ID/logs?flowRunId=RUN_ID. A completed test run verifies the tested trigger, not every future event. If no run appears, check account ownership, activation, and trigger matching before creating another flow. Preserve the flow ID and returned error if a write outcome is uncertain.
Later changes
For one trigger's on/off state, use blotato_update_automation_trigger with current flow and trigger IDs. At least one trigger must stay active while the flow is live. Updating flow content or triggers reissues trigger IDs, so read the response before a later trigger update.
For REST, use the DM Automations API. Trigger updates, flow updates, and archive operations have distinct schemas. Sending a test DM or creating a flow does not prove a real trigger run succeeded. Verify runs and logs.
Check or add credits
Prompt for your assistant:
Check my Blotato credit balance and account email. If I need more credits, tell me where to add them.
Call
blotato_get_creditsto read the balance, account email, pricing, and purchase limits.State the returned account email before directing the user to purchase credits. Credits belong to the account and are non-transferable.
Direct the user to Settings > Billing.
Recheck the balance after payment when requested.
Request and result
Call blotato_get_credits without arguments, or request GET https://backend.blotato.com/v2/credits with blotato-api-key: YOUR_API_KEY. Read creditsRemaining, accountEmail, purchaseQuantityRange, and pricePer1000CreditsUsd from the response. Do not substitute another plan's monthly allocation for the current balance.
The MCP server does not list a credit-purchase tool. Do not invent a checkout link. After the user finishes payment in Billing, read the balance again when requested and preserve any payment error for billing support.
See Credits reference for balance, pricing, and REST checkout fields.
REST API quickstart
Use this path for HTTP requests, n8n, or Make. To give instructions to Claude, Codex, or another assistant, start with MCP setup.
Your first verified result is an account-list response. Publishing comes after account selection and platform checks.
Get Started with Blotato API
The Blotato API allows you to:
publish and schedule posts directly to social media platforms
supports text, image, videos, reels, slideshows, carousels, threads, and stories
create images, videos, slideshows, and carousels programmatically via templates
It is limited to paying subscribers in order to reduce spam and service abuse, keeping Blotato's integration in good standing with the social platforms.
Plans That Include API
Free Trial
No
Starter
Yes
Creator
Yes
Agency
Yes
API access is included on every paid plan. Generating an API key from Settings > API immediately ends a free trial and activates your paid Starter subscription.
Base URLs
Blotato has two base URLs. Use the one that matches your integration:
REST API (direct HTTP, n8n, Make)
https://backend.blotato.com/v2
MCP Server (ChatGPT, Claude Code, Claude Cowork, Claude Desktop, Cursor, Antigravity)
https://mcp.blotato.com/mcp
api.blotato.com is not a valid base URL. If your AI tool reports a DNS error for api.blotato.com, it guessed wrong. Use one of the two URLs above.
1. Get Your API Key
❗IMPORTANT: this will end your free trial immediately and start your paid subscription.
Go to Accounts > API > click "Generate API Key".
2. Connect Social Accounts
Go to Accounts and connect your social accounts. If you get stuck, more information here:
3. Verify access
Ask your agent or HTTP client to send this request with your API key:
A successful response contains items. An empty items array confirms access but means no social accounts are connected. Use each account's returned id as accountId.
Next, follow Publish and verify a post, or choose another agent workflow. Use Accounts and identifiers for Page, board, and playlist IDs.
Optional: install the Blotato integration
n8n
Follow the Blotato node installation guide for n8n Cloud or self-hosted n8n.
Use the first-post workflow after selecting the intended account.
Make
Open any scenario in Make
Click the "+" icon to add a module
Search for "Blotato"
Select the Blotato module
Choose an automation tutorial
New to building automations? Start here:
Build Your First AI Automation - Build an n8n source-to-visual-to-post workflow with completion checks.
Choose your preferred integration path:
MCP Server - control Blotato from ChatGPT, Claude.ai, Claude Desktop, Claude Code, Cursor, and more with natural language
Blotato has official Make.com and n8n nodes. Zapier does not have an official Blotato app. In Zapier, use Webhooks by Zapier to send authenticated HTTP requests to the Blotato API.
Check out more workflow automation templates here:
Troubleshoot errors
Use the Logs and click on each request to see full payload, response, and error message:
Logs (for debugging): https://my.blotato.com/logs
FIX MY AUTOMATION (n8n only): On a failed n8n request in the Logs, click the green FIX MY AUTOMATION button and Blotato AI will attempt to fix your n8n workflow automatically. This feature is for n8n only -- it does not work for Make, Claude, MCP, or direct REST API calls. Full walkthrough: Fix My Automation.
Raw REST API Calls - Examples
Authentication
To authenticate API requests, include your Blotato API key in the request headers.
Authentication Header
Requests without a valid API key will be rejected and 401 error will be returned.
Your API key sometimes ends with one or more = characters. Copy the full value, including these characters. Use the quoting required by your client or configuration format. For a 401, follow authentication checks.
Step 0: Get Your Account IDs
Before publishing, fetch your connected accounts to get the accountId:
Use the id from the response as your accountId. For Facebook and LinkedIn, also fetch subaccounts to get pageId. See Accounts reference for details.
Post to a Platform Immediately
After submission, save postSubmissionId and poll GET /v2/posts/:postSubmissionId until published or failed. A 201 create response confirms acceptance. Follow the completion rules before reporting success.
Post at a Scheduled Time
Replace the example date with the user's intended future time in UTC. To use the next available calendar slot, replace scheduledTime with useNextFreeSlot: true. Both are top-level fields, outside post. See Scheduling.
Post a Twitter Thread with Multiple Posts
Attach Media to Post (images and videos)
Pass any publicly accessible image/video URL into the mediaUrls parameter. No upload step required. Blotato handles the media transfer.
For local files without a public URL, use the Presigned Upload endpoint to upload directly to Blotato. No Google Drive or S3 needed.
The optional Upload Media endpoint is still available if you need to host media on Blotato's servers. See Upload Media.
For AI Agents
If you are an AI agent or LLM integration, start with the plain-text API reference:
This index links to references by task, including request examples, status values, and workflow instructions.
For async workflow patterns and code examples, see Protocol and Recipes.
For the full endpoint reference, see API Reference.
Public API operation index
This index covers Blotato's public operations in the OpenAPI document. Use the linked reference for parameters and responses.
Base URL: https://backend.blotato.com. The paths below include /v2. Authenticate with blotato-api-key.
Additional documented routes
Account usage and schedule-slot management are implemented and documented separately, but are absent from this OpenAPI export. Their absence here does not mean the features are unavailable.
For first-time setup, use the REST quickstart. For tool calls, use the MCP tool catalog. The MCP catalog is not a generated copy of every REST operation.
Users
General
Use these endpoints to verify your API key and check account usage.
Endpoints
GET /v2/users/me
Fetches the current user's information, including subscription status and plan. This endpoint is useful for verifying that your API key is valid and referencing your own userId.
Response Keys
id
string
The unique ID of the user.
subscriptionStatus
string
The user's subscription status (e.g., active, generic_pro).
subscriptionPlan
string
The user's plan tier: starter, creator, or agency.
apiKey
string
[Sensitive] The user's API key.
Examples
Get verification info
Response 200 OK
GET /v2/users/me/usage
Returns the current user's connected-account usage, active-contact usage, and active-contact limit.
Use this endpoint before connecting more accounts or sending messages at scale so you know how close you are to your plan limits. For the limit values on each plan, see Plan Limits.
Response Keys
accounts
integer
Number of connected channels counting toward the connected-accounts limit. Facebook Pages count. The Facebook login itself does not count. LinkedIn profiles and LinkedIn company Pages count.
contacts
integer
Number of contacts messaged this month, counting toward the active-contacts limit.
contactsLimit
integer or "unlimited"
Maximum active contacts you can message this month. This matches your current account limit, including any custom active-contact limit on your account.
Get usage
Response 200 OK
Accounts
List Connected Accounts
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /users/me/accounts
Method: GET
Description
Returns all social media accounts connected to your Blotato account. Use this to get the accountId required for publishing posts.
Query Parameters
platform
string
No
Filter by platform. Values: twitter, instagram, linkedin, facebook, tiktok, pinterest, threads, bluesky, youtube
The platform values here are the same values used in content.platform and target.targetType when publishing.
Response
Status Code: 200 OK
items
array
List of connected accounts
items[].id
string
Account ID. Use this as accountId when publishing.
items[].platform
string
Platform type (e.g., twitter, facebook, instagram)
items[].fullname
string
Display name of the account
items[].username
string
Username or handle
If no accounts are returned, the user needs to connect social accounts in Accounts.
Examples
List all accounts
Filter by platform
List Subaccounts (Pages)
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /users/me/accounts/:accountId/subaccounts
Method: GET
Description
Returns subaccounts for a connected account. Subaccounts include Facebook Pages, LinkedIn Company Pages, and YouTube Playlists. Use this to get the pageId required for publishing to Facebook/LinkedIn, or playlistIds for adding YouTube videos to playlists.
Path Parameters
accountId
string
Yes
The account ID from the List Accounts endpoint
Response
Status Code: 200 OK
items
array
List of subaccounts
items[].id
string
Subaccount ID. Use this as target.pageId when publishing to Facebook or LinkedIn.
items[].accountId
string
Parent account ID
items[].name
string
Name of the page
If subaccounts is empty, the user needs to connect a Facebook Page, LinkedIn Company Page, or YouTube account in Accounts.
Example
List Available LinkedIn Pages
Use GET /v2/integrations/oauth2/linkedin/pages?accountId=ACCOUNT_ID to list organization pages the connected LinkedIn account administers. accountId is required and comes from List Connected Accounts.
The response contains items, each with id, name, and isActive. isActive: true means Blotato is already connected to the page. This endpoint discovers available pages. For publishing, retrieve connected page IDs through List Subaccounts above.
Connect missing pages in Accounts, then repeat the subaccounts lookup. A 422 response for an expired connection requires reconnection. The route limit is 20 requests per minute.
How to Get the Right IDs for Publishing
Different platforms need different IDs. Here is how to get them for each platform.
Twitter, Instagram, TikTok, Threads, Bluesky
These platforms need only an accountId:
Call
GET /v2/users/me/accounts?platform=twitter(replace with your platform)Use
items[].idasaccountIdin your publish requestIf multiple accounts are returned, use
fullnameorusernameto identify the correct one, or ask the user which account to use
YouTube
YouTube needs an accountId. To add videos to playlists, also fetch subaccounts to get playlist IDs:
Call
GET /v2/users/me/accounts?platform=youtubeUse
items[].idasaccountIdCall
GET /v2/users/me/accounts/{accountId}/subaccountsUse
items[].idvalues astarget.playlistIdsin your publish requestplaylistIdsis optional -- omit it to publish without adding to a playlist
Facebook requires both accountId and pageId:
Call
GET /v2/users/me/accounts?platform=facebookUse
items[].idasaccountIdCall
GET /v2/users/me/accounts/{accountId}/subaccountsUse
items[].idastarget.pageIdin your publish requestIf multiple pages are returned, use
nameto identify the correct one, or ask the user which page to use
Full example:
LinkedIn Company Page
To post to a LinkedIn Company Page instead of your personal profile:
Call
GET /v2/users/me/accounts?platform=linkedinUse
items[].idasaccountIdCall
GET /v2/users/me/accounts/{accountId}/subaccountsUse
items[].idastarget.pageIdIf you skip
pageId, the post goes to your personal LinkedIn profile
Pinterest requires a boardId. Fetch boards with the List Pinterest Boards endpoint:
Call
GET /v2/users/me/accounts?platform=pinterestUse
items[].idasaccountIdCall
GET /v2/social/pinterest/boards?accountId={accountId}Use
items[].idastarget.boardIdin your publish requestIf multiple boards are returned, use
nameto identify the correct one, or ask the user which board to use
Web app shortcut: you can also grab a Board ID without the API. Go to Accounts, scroll to your Pinterest account, and select a Board -- Blotato copies its Board ID to your clipboard. Use this if the boards endpoint returns an empty list.
Full example:
List Pinterest Boards
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /social/pinterest/boards
Method: GET
Description
Returns boards owned by a connected Pinterest account. Use this to get the boardId required when publishing a pin.
Query Parameters
accountId
string
Yes
Blotato Pinterest account ID from GET /users/me/accounts.
Response
Status Code: 200 OK
items
array
List of Pinterest boards (max 250)
items[].id
string
Board ID. Use this as target.boardId when publishing a pin.
items[].name
string
Display name of the board on Pinterest
Example
Credits /v2/credits
Blotato credits pay for AI generations such as videos and images. Use these endpoints to check your remaining credit balance, see current pricing, and buy more credits. Two endpoints:
Get Credit Balance —
GET /v2/creditsBuy Credits —
POST /v2/credits
Credits belong to a single account and are non-transferable. Confirm the account email from Get Credit Balance before you buy, so the credits land on the account you intend.
Get Credit Balance
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /credits
Method: GET
Description
Returns your remaining credits, the email of the account the API key belongs to, and current purchase pricing.
Response
Status Code: 200 OK
creditsRemaining
integer
Credits left on the account.
accountEmail
string
Email of the account the API key belongs to.
purchaseQuantityRange
object
Allowed purchase range, with min and max credits per purchase.
pricePer1000CreditsUsd
number
Price in US dollars per 1,000 credits.
Example response:
Errors
401
Missing or invalid API key.
500
Server error.
Buy Credits
Endpoint
URL: /credits
Method: POST
Description
Creates a Stripe Checkout link to buy credits. Creating the link does not charge anything. The account owner opens the link in a browser and completes payment there, and the purchased credits land on this account. Stripe creates an invoice for the credit purchase after checkout succeeds. Buy between 1,000 and 10,000 credits per request.
Confirm the account email from Get Credit Balance first, since credits are non-transferable between accounts.
Request Body
quantity
integer
Yes
Credits to buy. Between 1,000 and 10,000.
referral
string
No
Optional referral code.
Response
Status Code: 201 Created
checkoutUrl
string
Stripe Checkout URL. Open it in a browser to complete payment. No charge happens until checkout completes.
Example response:
Errors
400
The quantity is outside the 1,000 to 10,000 range, or the request body is invalid.
401
Missing or invalid API key.
429
Rate limit exceeded (10 requests per hour).
500
Server error.
Pricing
Credits cost $6.00 per 1,000 credits. Read the current price from Get Credit Balance (pricePer1000CreditsUsd), since pricing changes over time.
Upload Media /v2/media
Upload is Now Optional
You no longer need to upload media to Blotato before publishing. You can pass any publicly accessible image/video URL directly into the mediaUrls parameter in the Publish node. Blotato handles the media transfer automatically.
For local files without a public URL, use the Presigned Upload endpoint below. This lets you upload directly to Blotato without needing Google Drive, S3, or any other intermediate storage. Upload size depends on your plan (see Plan Limits).
The legacy Upload Media endpoint is still available if you prefer to use it, or if you need to host media on Blotato's servers.
Upload Media
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /media
Method: POST
Description
This endpoint allows users to upload media by providing a URL. The uploaded media will be processed and stored, returning a new media URL that is used to publish a new post. Most of the platforms require validated URLs for posting images.
You can upload:
publicly accessible URLs
base64 encoded image data
Media uploads are subject to your plan's upload size limit. See Plan Limits for more details.
If you are using the n8n "Binary Data" upload option, the file size limit is 15MB. For larger files, use the Presigned Upload endpoint above (no external hosting needed), or host your media on Google Drive, AWS S3, or another cloud storage service and pass the URL instead.
Request
Request Body
url
string
✅
The URL of the media to upload.
Responses
Success Response
Status Code: 201 Created
Response Body:
Error Responses
Internal Server Error
Status Code: 500 Internal Server Error
Too Many Requests
Media upload has a user-level rate limit of 30 requests / minute.
Status Code: 429 Too many requests
Error Codes
The following client error codes may be returned:
90009
Blotato could not fetch the media URL. Confirm the URL loads or downloads without signing in, then try again.
9999
Unknown error.
Examples
1. Upload Media
Response:
Presigned Upload (Local Files)
Upload local files directly to Blotato without hosting them on Google Drive or S3 first. This is the recommended approach for MCP users and anyone working with local files.
Endpoint
URL: /media/uploads
Method: POST
Rate limit: 120 requests per minute
Request
Request Body
filename
string
Yes
Filename with extension (e.g., "photo.jpg", "video.mp4"). Used to determine content type.
Response
Status Code: 201 Created
presignedUrl-- upload your file here via HTTP PUT. Expires after a short period.publicUrl-- the final public URL to use inmediaUrlswhen publishing.
Complete Example: Upload a Local File and Post It
Three steps: get the presigned URL, upload the file, then publish the post.
Step 1: Get a presigned upload URL
Response:
Step 2: Upload the file to the presigned URL
Use the correct Content-Type for your file (image/jpeg, image/png, video/mp4, etc.).
Step 3: Publish a post using the public URL
Max file size depends on your plan. See: Plan Limits for more details. The presigned URL expires after a short period -- upload the file immediately after receiving it.
Troubleshooting: presigned PUT fails in Claude Cowork or Claude Desktop
If POST /v2/media/uploads returns a presignedUrl but the PUT step to that URL fails with a sandbox, proxy, network egress, or "Stream closed" error, this is a Claude Cowork / Claude Desktop sandbox restriction, not a Blotato API issue.
Fix it by allowlisting database.blotato.io in Cowork's network egress settings. Full steps: Presigned upload PUT fails / "Sandbox error" / network egress blocked.
For Claude Code (sandbox not user-configurable), skip the local upload entirely and pass a public URL into mediaUrls directly.
Using Google Drive as a Media Source
Google Drive share links open a viewer page, not a direct file. Blotato needs a direct file URL to fetch and read media.
Set sharing permissions
For automation workflows (n8n, Make.com), set the entire Google Drive folder to "Anyone with the link" as Viewer. All files inside that folder inherit the same permission, so you do not need to set permissions on each file individually.
For one-off uploads, set the individual file to "Anyone with the link" as Viewer.
Common Google Drive URL Errors
Folder URLs don't work: If your link looks like /drive/folders/..., it's a folder link. Blotato needs a direct link to a specific file, not a folder.
Preview URLs don't work reliably: If your link ends with /view?..., it points to Google Drive's preview page, not the raw file.
Use the direct download URL format
For Google Drive files, including large videos, first replace the standard share link with this format:
Replace {FILE_ID} with the ID from your share link. For example, if your share link is:
The file ID is 1aBcDeFgHiJkLmNoPqRsTuVwXyZ, so the direct URL is:
Make sure the file is shared with "Anyone with the link" as Viewer.
The confirm=t parameter requests the file download from Google Drive. Blotato does not impose a 100 MB Google Drive cutoff. The file still must fit your Blotato plan's upload limit and the destination platform's media limit.
Seeing error "Google Drive can't scan this file for viruses"?
Google Drive sometimes returns a virus-scan warning page instead of the file for large videos. Blotato converts Google Drive share links to the direct download format above, but Google Drive might still return the warning page.
If the direct download URL still returns the warning page, use the Presigned Upload flow, frame.io, AWS S3, or Google Cloud Storage. These options avoid the Google Drive warning page.
Publish Post /v2/posts
Publishing a Post
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /posts
Method: POST
Rate Limit: 30 requests / minute
Description
Publish a new post to a social media platform. The request must include the post content, target platform, and an accountId (fetched from GET /v2/users/me/accounts).
After submitting, poll Get Post Status with the returned postSubmissionId to track publishing progress.
Before You Start
Fetch your connected accounts:
GET /v2/users/me/accounts(docs)Fetch your subaccounts to get
pageIdfor Facebook/LinkedIn andplaylistIdsfor YouTube:GET /v2/users/me/accounts/{accountId}/subaccounts(docs).For a social platform, set
content.platformandtarget.targetTypeto the same value (e.g., both"twitter"). The webhook target usesotherandwebhook.
Request Body
The request body has two top-level fields: post (required) and optional scheduling fields. Do not nest scheduling fields inside post.
post
object
Yes
The post content and metadata.
scheduledTime
string
No
ISO 8601 timestamp with timezone offset for the requested future time. Use this without useNextFreeSlot: true.
useNextFreeSlot
boolean
No
Schedule at the next available slot time. Defaults to false. Requires an available slot matching the platform, account, and Page.
Scheduling behavior:
Choose 1 scheduling method. If
scheduledTimeis set, it supplies the publish time. SettinguseNextFreeSlot: trueas well still runs slot validation and fails when no matching slot is available. Do not combine the fields.If
useNextFreeSlotistrue(and noscheduledTime): the post is scheduled at the next available calendar slot matching the destination.If neither
scheduledTimenoruseNextFreeSlotis provided: the post publishes immediately.Both fields must be root-level (siblings of
post). If they are nested insidepost,options, or any other object, they are ignored and the post publishes immediately.
post Object
accountId
string
Yes
The account ID from GET /v2/users/me/accounts.
content
object
Yes
The content of the post. See content below.
target
object
Yes
The target platform and platform-specific fields. See target below.
content Object
text
string
Yes
The text content of the post.
mediaUrls
array of strings
Yes
Array of media URLs. Pass any publicly accessible URL -- no upload step required. Pass [] for text-only posts.
platform
string
Yes
For social platforms, match target.targetType. Use other for the webhook target. Values: twitter, linkedin, facebook, instagram, pinterest, tiktok, threads, bluesky, youtube, other
additionalPosts
array
No
Additional posts for threads (Twitter, Bluesky, Threads). Each has text and mediaUrls.
other is reserved for publishing to a custom webhook. It does not represent another native social platform.
target Object
The target object requires targetType and platform-specific fields. Match content.platform for social platforms. For a custom webhook, use content.platform: "other" with target.targetType: "webhook".
Quick Reference: Required Fields Per Platform
Platform
targetType
Required Fields
Optional Fields
"twitter"
(none)
(none)
"linkedin"
(none)
pageId
"facebook"
pageId
mediaType, link, firstComment
"instagram"
(none)
mediaType, altText, collaborators, coverImageUrl, shareToFeed, audioName, trial, firstComment
TikTok
"tiktok"
privacyLevel, disabledComments, disabledDuet, disabledStitch, isBrandedContent, isYourBrand, isAiGenerated
title, autoAddMusic, isDraft, imageCoverIndex, videoCoverTimestamp
"pinterest"
boardId
title, altText, link
Threads
"threads"
(none)
replyControl
Bluesky
"bluesky"
(none)
(none)
YouTube
"youtube"
title, privacyStatus, shouldNotifySubscribers
isMadeForKids, containsSyntheticMedia, playlistIds, thumbnailUrl
Webhook
"webhook"
url
(none)
targetType
"twitter"
Yes
targetType
"linkedin"
Yes
Carousels: Pass 2-10 image URLs (JPG, PNG) in content.mediaUrls. Blotato auto-builds a LinkedIn Document carousel (LinkedIn's modern PDF-based carousel format — viewers swipe through pages). Videos cannot be mixed into a carousel.
targetType
"facebook"
Yes
mediaType
"reel" or "story"
See description
Video posts must use "reel" (regular feed videos no longer supported). Set "story" for Stories. Omit (default) for text-only or image posts. Stories require one video or image attachment; if more than one is provided, only the first is used. See Facebook Reel requirements.
link
string
No
URL to attach as a link preview.
firstComment
string
No
Auto-posts this text as the first comment right after the post publishes. Up to 8000 characters. Works on feed posts and reels, not Stories.
targetType
"instagram"
Yes
mediaType
"reel" or "story"
No
Default: "reel" for videos. Set "story" to publish one image or video as an Instagram Story.
altText
string
No
Alt text for images. Up to 1000 characters.
collaborators
array of strings
No
Instagram handles to tag (max 3). Do not include the @ sign. Single image posts and reels only - not supported on carousels (multi-media posts), which will fail to publish.
coverImageUrl
string
No
Cover image URL for reels. Max 8MB.
shareToFeed
boolean
No
Share the reel to the Instagram feed. Only applies to reels.
audioName
string
No
Custom audio name for reels. You can only set this once per reel.
trial
object
No
Settings for trial reels. Trial reels are shown to non-followers first. Only applies to reels. See trial object below.
firstComment
string
No
Auto-posts this text as the first comment right after the post publishes. Up to 2200 characters. Works on posts, carousels, and reels, not Stories. Useful for putting a link in the first comment.
Instagram Stories do not support captions through Meta's publishing API. Set the required content.text field to an empty string for a Story. To display text, render it into the image or video before publishing. Native Story text, link stickers, and other interactive stickers require manual editing in Instagram. See Instagram limitations.
trial Object
graduationStrategy
string
Yes
"MANUAL" (you promote to followers manually) or "SS_PERFORMANCE" (Instagram auto-promotes based on performance).
TikTok
targetType
"tiktok"
Yes
privacyLevel
string
Yes
SELF_ONLY, PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, or FOLLOWER_OF_CREATOR
disabledComments
boolean
Yes
disabledDuet
boolean
Yes
disabledStitch
boolean
Yes
isBrandedContent
boolean
Yes
Set true only for a paid partnership with a third-party brand. Adds TikTok's paid-partnership disclosure. Set false for organic content.
isYourBrand
boolean
Yes
Set true when the post promotes your own brand, product, or business. This drives TikTok's "Promotional content" disclosure. Set false for organic content.
isAiGenerated
boolean
Yes
Set true when the content is AI-generated. This drives TikTok's AI-generated label. Set false for content you filmed or made yourself.
title
string
No
Title for image posts. Max 90 characters. No effect on videos.
autoAddMusic
boolean
No
Add music to photo posts. No effect on videos. Default: false.
isDraft
boolean
No
Post as a draft. Drafts appear in TikTok mobile app notifications, not the Drafts folder.
imageCoverIndex
number
No
Index (starting from 0) of image to use as cover for carousels.
videoCoverTimestamp
number
No
Timestamp in milliseconds to use as video cover.
For organic content that is not sponsored and not AI-generated, set isBrandedContent, isYourBrand, and isAiGenerated to false. Set isYourBrand to true only to promote your own brand, and isAiGenerated to true only for AI-generated content. Each field maps to a separate TikTok content disclosure, so set only the ones that apply.
targetType
"pinterest"
Yes
title
string
No
Pin title.
altText
string
No
Pin alt text.
link
string
No
Pin URL link.
Pinterest "description" comes from the content.text field.
Threads
targetType
"threads"
Yes
replyControl
string
No
everyone, accounts_you_follow, or mentioned_only
Bluesky
targetType
"bluesky"
Yes
YouTube
targetType
"youtube"
Yes
title
string
Yes
Video title.
privacyStatus
string
Yes
private, public, or unlisted
shouldNotifySubscribers
boolean
Yes
isMadeForKids
boolean
No
Default: false
containsSyntheticMedia
boolean
No
Whether media contains AI-generated content.
thumbnailUrl
string
No
Publicly accessible image URL to use as the video thumbnail. Requires a verified YouTube account with custom thumbnail capabilities.
YouTube "description" comes from the content.text field. Tags are not supported -- YouTube recommends against relying on tags for discovery (source).
Webhook
This target is available through REST, not blotato_create_post. Set content.platform to "other" and target.targetType to "webhook". It sends post content to your URL. It is separate from the DM automation webhook action and does not subscribe you to account-wide events.
targetType
"webhook"
Yes
url
string
Yes
The webhook URL to send the post data.
Response
Status Code: 201 Created
postSubmissionId
string
ID of the post submission. Use it to poll Get Post Status for publishing progress.
scheduledTime
string
The resolved UTC time the post publishes. Absent when the post publishes immediately.
scheduledTime tells you the slot Blotato picked when you send useNextFreeSlot: true, so you read the scheduled time without a follow-up call.
Failed posts are visible at https://my.blotato.com/posts?status=failed. The most common cause of failed posts is incorrect JSON structure.
Examples
1. Simplest Post (Twitter, text only)
2. Instagram Post with Images
Posting multiple images to Instagram creates a carousel.
firstComment auto-posts as the first comment right after the post goes live, a common way to share a link without putting it in the caption.
3. Facebook Page Post
Get accountId and pageId from the Accounts endpoints.
4. TikTok Post (all required fields)
5. Scheduled Post
6. Twitter Thread
Threads work for Twitter, Bluesky, and Threads.
7. Schedule at Next Free Slot
useNextFreeSlot and scheduledTime are top-level fields, not inside post.
Get Post /v2/posts/:postSubmissionId
Check Post Status
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /posts/:postSubmissionId
Method: GET
Rate Limit: 60 requests / minute
Description
Poll this endpoint to check the publishing status of a post. After submitting a post with Create Post, use the returned postSubmissionId to track its progress.
The lookup checks failed, published, and scheduled records belonging to the authenticated Blotato user. If none matches, it returns in-progress. This fallback does not confirm a live queue job or validate a guessed submission ID. Use the original create response and account credentials.
Request
Path Parameters
postSubmissionId
string
Yes
The post submission ID returned by the Create Post endpoint.
Responses
Success Response
Status Code: 200 OK
The response shape depends on the current status:
Published (terminal - success):
Failed (terminal - error):
In Progress (keep polling):
Scheduled (queued for a future time):
Response Keys
postSubmissionId
string
The post submission ID.
status
string
One of: in-progress, scheduled, published, failed.
scheduledTime
string
The scheduled publish time. Present when status is scheduled.
publicUrl
string
URL returned for a published result, when available. The field is optional.
errorMessage
string
Description of the failure. Present when status is failed.
Polling Strategy
Wait at least 10 seconds between status requests.
Continue while status is
in-progress, within a defined attempt or elapsed-time limit. Verify the ID came from the original create response.If status is
scheduled, report the returnedscheduledTimeand stop this polling loop. Scheduling is confirmed, not publication.Stop when status is
published(success) orfailed(error).On
failed, inspecterrorMessageand the destination before deciding whether a corrected or delayed retry is appropriate. Do not repeat a create request blindly.
If the result remains unresolved, retain the ID and follow publishing-status diagnosis. A polling deadline is not proof of failure.
Failed posts are also visible at https://my.blotato.com/posts?status=failed.
Example
List Posts /v2/posts
List Posts
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /posts
Method: GET
Rate Limit: 60 requests / minute
Description
Returns the current user's posts (scheduled, published, and failed) within a time window, ordered by post time (most recent first). Supports cursor-based pagination and filtering by status and platform.
To check the status of a single post by its postSubmissionId, use Get Post Status instead.
Query Parameters
since
string
No
Only include posts whose post time is on or after this ISO 8601 timestamp. Defaults to 7 days ago.
until
string
No
Only include posts whose post time is on or before this ISO 8601 timestamp. Defaults to 7 days from now.
limit
integer
No
Number of items per page. Min: 1, Max: 250. Default: 50.
cursor
string
No
Pagination cursor from a previous response. Pass it to fetch the next page.
status
string[]
No
Filter by status. One or more of scheduled, published, failed. Pass multiple values to include any of them. Omit to include all statuses.
platform
string[]
No
Filter by social media platform. One or more of twitter, instagram, linkedin, facebook, tiktok, pinterest, threads, bluesky, youtube. Pass multiple values to include any of them. Omit to include all platforms.
Array query parameters are repeated, e.g. ?status=scheduled&status=published.
Response
Status Code: 200 OK
Response Keys
items
array
List of posts within the time window, ordered by postTime descending.
items[].id
string
The post's identifier. Distinct per state.type: scheduled posts use the schedule ID, published posts use the published post ID, failed posts use the failed post ID.
items[].postTime
string
ISO 8601 UTC timestamp. For scheduled posts this is the planned publish time; for published posts it is when the post was published; for failed posts it is when the failure was recorded.
items[].platform
string
Social media platform.
items[].text
string
The post text.
items[].mediaUrls
string[]
URLs of attached media (images, video). Empty when text-only.
items[].account
object or null
Connected account with id, name, and subaccount. Null if the account is no longer connected.
items[].state
object
Discriminated union; see below.
cursor
string
Pagination cursor. Pass this as the cursor query parameter to fetch the next page. Absent when there are no more pages.
state object
The shape depends on state.type:
Scheduled
Published
postUrl
string | null
The live URL of the published post. Null if the platform did not return one.
analytics
object | null
Latest snapshot under latest and every snapshot, oldest first, under history. Null if metrics have not been collected or analytics is unavailable.
Failed
errorMessage
string | null
Human-readable description of the failure.
Errors
422
Invalid since, until, or cursor value.
Examples
Default request
Only published Twitter posts in the last 30 days
Scheduled or published, multi-platform
Walking pages
If the response contains a cursor, pass it on the next request:
When the response omits cursor, you have reached the end of the list.
List Published Posts /v2/published-posts
List your published posts, filtered by text and platform, with each post's latest analytics snapshot attached. Use this to find a published post and its id, or to browse recent posts with their current metrics.
For engagement rankings and full metric history, see Analytics.
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /published-posts
Method: GET
Description
Returns your published posts, newest or oldest first, filtered by an optional full-text query and platform. Each item carries its latest metrics snapshot. Results use offset-based pagination with a total count.
Query Parameters
query
string
No
Full-text search over post content. Omit to include all posts.
platform
string
No
Filter to one platform. Omit to include all platforms.
sortBy
string
No
Sort order: newest or oldest. Default newest.
offset
integer
No
Number of posts to skip before the page. Default 0.
limit
integer
No
Number of posts to return. Min: 1, Max: 100. Default: 20.
Response
Status Code: 200 OK
items
array
Published posts for this page.
items[].content
string
The post text.
items[].postUrl
string or null
Live URL of the published post. Null if the platform did not return one.
items[].platform
string
Social media platform.
items[].createdAt
string
ISO 8601 timestamp when the post was published.
items[].mediaUrls
string[]
URLs of attached media. Empty when text-only.
items[].latestMetrics
object
The most recent metrics snapshot. Absent if no metrics have been collected yet. See Metrics.
items[].metricsHistory
array
Collected snapshots, oldest first. Each is { fetchedAt, metrics }.
count
integer
Total number of posts matching your search, across all pages.
To page through results, increase offset by limit on each call until offset reaches count.
Errors
422
Invalid sortBy, offset, or limit value.
Example
Get a Published Post
URL: /published-posts/:id
Method: GET
Returns 1 published post by its Blotato published-post ID.
rawPost contains the original publish payload for posts published through Blotato and is null for other posts. The endpoint returns 404 when the ID does not exist or does not belong to the authenticated user.
Analytics /v2/analytics
Blotato collects engagement analytics for your published posts on 8 platforms: Twitter/X, Instagram, Facebook, Threads, Bluesky, TikTok, YouTube, and Pinterest. Analytics for LinkedIn are not available yet. Four read-only endpoints expose this data:
List Top Performing Posts —
GET /v2/analyticsList Performance by Platform —
GET /v2/analytics/platformsGet Analytics Summary —
GET /v2/analytics/summaryGet Post Analytics —
GET /v2/posts/{id}/analytics
Analytics is available on all paid plans, both in the Analytics dashboard and via the API documented below. Fair usage limits may apply in the future.
For a web-app and AI-agent walkthrough, see Analytics.
Both endpoints return the latest snapshot Blotato has already collected. They do not trigger a fresh fetch from the social platform.
Using analytics from Make.com or n8n
The official Blotato Make.com module does not include analytics yet. To pull analytics from a Make scenario, call the two endpoints on this page with Make's HTTP module, passing your API key in the blotato-api-key header. The same approach works in n8n with the HTTP Request node.
Collection schedule
Blotato collects a snapshot of each post's metrics at fixed checkpoints, measured from when the post publishes. Higher plans collect more often and keep collecting longer.
Starter
4
30 days
Day 1, then days 7, 14, and 30
Creator
18
30 days
2 hours, daily through day 8, then every 2-3 days through day 30
Agency
20
90 days
2 and 6 hours, daily through day 8, every 2-3 days through day 30, then day 90
Full checkpoint list per plan:
Starter: 1d, 7d, 14d, 30d
Creator: 2h, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 10d, 12d, 14d, 17d, 20d, 22d, 24d, 27d, 30d
Agency: 2h, 6h, 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 10d, 12d, 14d, 17d, 20d, 22d, 24d, 27d, 30d, 90d
Each checkpoint adds a small random offset to spread out collection, so exact timing varies by a few minutes on the early checkpoints and up to a day on the 30-day and 90-day ones. After the final checkpoint, Blotato stops collecting and the last snapshot stays as the post's metrics.
Posts stuck on "Analytics pending"
"Analytics pending" means no metric history is available. It does not identify the cause.
Check the platform and plan against the supported metrics.
Check whether the post was published through Blotato with analytics enabled.
Compare the post's age with its plan's checkpoints.
Inspect
lastErrorand the account's connection state. Reconnect when authorization is missing or expired, not as a repeated generic fix.If the expected checkpoint has passed and no cause is established, give support the published post ID, publication time, platform, plan, last fetch time, and error.
Reconnection does not guarantee a 24-48-hour backfill or a restart of every historical post's schedule. See new connections and pending data.
YouTube view counts trail the public count
For YouTube, Blotato reads the YouTube Analytics API, which reports only finalized views after YouTube filters spam and invalid traffic. The count on the YouTube watch page updates in near real time and includes views YouTube has not validated yet, so it reads higher. The two numbers are not expected to match, and the gap narrows as YouTube finalizes more data.
See: Why is my YouTube view count in Blotato lower than on YouTube?
List Top Performing Posts
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /analytics
Method: GET
Description
Returns your top performing published posts, ordered by the requested metric over a time range. Each item includes its latest metrics snapshot and full snapshot history.
Query Parameters
since
string
No
Only include posts published on or after this ISO 8601 timestamp. Defaults to 30 days ago.
until
string
No
Only include posts published on or before this ISO 8601 timestamp. Defaults to now.
platform
string
No
Filter to one platform: twitter, instagram, facebook, threads, bluesky, tiktok, youtube, or pinterest. Omit to include all platforms. Analytics for linkedin are not available yet, so filtering to it returns no metrics.
sortBy
string
No
Metric to rank by. One of likes_count, comments_count, views_count, reach_count. Default: views_count. For Twitter/X, comments_count uses replies_count when comments are not reported, and views_count uses impressions_count when views are not reported.
limit
integer
No
Number of posts to return. Min: 1, Max: 100. Default: 20.
Response
Status Code: 200 OK
Response Keys
items
array
Published posts, ordered by the requested sortBy metric (highest first). Twitter/X rankings use replies_count as the comments fallback and impressions_count as the views fallback.
items[].content
string
The post text.
items[].postUrl
string | null
Live URL of the published post. Null if the platform did not return one.
items[].platform
string
Social media platform.
items[].createdAt
string
ISO 8601 timestamp when the post was published.
items[].mediaUrls
string[]
URLs of attached media. Empty when text-only.
items[].latestMetrics
object
The most recent metrics snapshot. Absent if no metrics have been collected yet. See Metrics.
items[].metricsHistory
array
All collected snapshots, oldest first. Each is { fetchedAt, metrics }.
Errors
422
Invalid since, until, sortBy, or limit value.
Example
List Performance by Platform
URL: /analytics/platforms
Method: GET
Returns 1 entry per platform with analytics, ordered by engagement. Totals use the latest snapshot of each post published in the window.
since
string
No
Include posts published on or after this ISO 8601 timestamp. Defaults to 24 hours ago.
until
string
No
Include posts published on or before this ISO 8601 timestamp. Defaults to now.
bucket
string
No
Time bucket size: hour or day. Defaults to hour.
Each item contains platform, postsCount, engagementsCount, likesCount, commentsCount, viewsCount, and buckets. Counts are strings except postsCount. viewsCount is null when the platform reports neither views nor impressions. Engagements are the sum of likes, comments or replies, shares, and saves.
Get Analytics Summary
URL: /analytics/summary
Method: GET
Returns published and failed post counts for a time window, both in total and grouped by platform and time bucket. It also returns metric totals from each published post's latest snapshot.
since
string
No
Include posts published or failed on or after this ISO 8601 timestamp. Defaults to 30 days ago.
until
string
No
Include posts published or failed on or before this ISO 8601 timestamp. Defaults to now.
bucket
string
No
Time bucket size: hour or day. Defaults to hour.
The response contains publishedCount, failedCount, platforms, buckets, and metrics. metrics contains postsCount, viewsCount, likesCount, and commentsCount, or is null when analytics is unavailable.
Get Post Analytics
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /posts/{id}/analytics
Method: GET
Description
Returns the latest metrics and full snapshot history for a single published post.
The id is the published post id, which you get from the items[].id field of List Top Performing Posts or List Posts (published items). It is not the postSubmissionId returned when you publish.
If your request returns only postSubmissionId, status, and publicUrl with no metrics fields, you called Get Post Status instead of this analytics endpoint. Get Post checks publish status with the postSubmissionId. Analytics uses the published post id from List Posts or List Top Performing Posts.
Path Parameters
id
string
Yes
The published post ID from items[].id in List Top Performing Posts or a published item in List Posts. Do not substitute a postSubmissionId. The analytics path ends in /analytics, whereas the publishing-status path does not.
Response
Status Code: 200 OK
Response Keys
publishedPostId
string
The id of the published post.
platform
string
Social media platform.
lastFetchedAt
string | null
ISO 8601 timestamp of the last snapshot stored successfully. A failed fetch leaves this unchanged, so it reflects the last success, not the last attempt. Check lastError for the most recent failure.
lastError
string | null
The last error Blotato hit while fetching metrics for this post, if any.
history
array
All collected snapshots, oldest first. Each is { fetchedAt, metrics }.
Errors
404
No published post with that id, it does not belong to your account, or your plan does not include analytics.
Example
Metrics
Every metric field is optional and only appears when the platform reports it for that post. Count metrics are returned as strings to preserve large integers (e.g. "18400"). Rate and percentage metrics are returned as numbers, and breakdown metrics (such as facebookPostReactionsByType) return an object mapping each bucket to a count, e.g. { "like": "13", "haha": "2" }.
A metric value of 0 is real and is always returned. It means zero, not missing.
Empty vs null metrics
An empty metrics object ({}) is not the same as metrics: null.
metrics: null-- no analytics snapshot has been stored yet.metrics: {}-- a snapshot exists, but no metric values are being returned. Two causes: every value came back empty from the platform, or your plan returns a reduced metric set.
Common metrics like viewsCount, likesCount, and reachCount apply across platforms. Each platform also returns its own metrics, prefixed with the platform name — for example twitterRetweetsCount or blueskyRepostsCount.
See the Metrics Reference for the full list of common and platform-specific metrics.
Platform-specific coverage depends on your plan. The Starter plan returns a limited set of these metrics. The Creator and Agency plans return every platform-specific metric and breakdown. See the Metrics Reference for the field-level breakdown.
Inspect the metrics object in the response for the set available for your post.
Related
List Posts — list scheduled, published, and failed posts; published items carry the
idused by Get Post Analytics.List Published Posts — full-text search over your published posts with the latest analytics snapshot attached.
Analytics Metrics Reference
This page lists every metric field that can appear in an analytics snapshot returned by List Top Performing Posts and Get Post Analytics.
Metrics live inside a snapshot's metrics object:
How to read this reference
Every field is optional. A metric only appears when the platform reports it for that specific post and when it's covered under your Blotato plan, so most snapshots contain a small subset of the fields below.
Counts are strings. Count metrics are returned as strings (e.g.
"18400") to preserve large integers without precision loss.Rates and percentages are numbers. Ratios (
0–1) and percentages (0–100) are returned as JSON numbers.Breakdown metrics are objects. A breakdown maps each bucket to a count string, e.g.
{ "like": "13", "haha": "2" }. On the Published page these render as a bar chart with one bar per bucket.Per-media metrics are arrays. A few Twitter video metrics are arrays indexed by media position in the post (upload order across the whole thread). Entries are
nullfor media items that are not videos.
Analytics are currently collected for Twitter/X, Instagram, Facebook, Threads, Bluesky, TikTok, YouTube, and Pinterest. Instagram and TikTok report only the common metrics and have no platform-specific fields. The LinkedIn fields below are part of the API schema but are not populated yet.
Common metrics
Reported across platforms whenever the platform exposes them.
viewsCount
string
Views.
✓
✓
✓
impressionsCount
string
Impressions.
✓
✓
✓
reachCount
string
Unique accounts reached.
✓
✓
✓
likesCount
string
Likes.
✓
✓
✓
commentsCount
string
Comments.
✓
✓
✓
repliesCount
string
Replies.
✓
✓
✓
sharesCount
string
Shares.
✓
✓
✓
savesCount
string
Saves / bookmarks.
✓
✓
✓
clicksCount
string
Link or content clicks.
✓
✓
✓
followsCount
string
Follows gained from the post.
✓
✓
✓
playsCount
string
Video / audio plays.
✓
✓
✓
profileVisitsCount
string
Profile visits driven by the post.
✓
✓
✓
profileActivityCount
string
Profile actions driven by the post.
✓
✓
✓
navigationsCount
string
In-post navigation actions (e.g. carousel swipes).
✓
✓
✓
interactionsSum
string
Total interactions.
✓
✓
✓
viewTimeMsSum
string
Total watch time, milliseconds.
✓
✓
✓
watchTimeMsAvg
string
Average watch time, milliseconds.
✓
✓
✓
Twitter / X
Post-level metrics.
twitterRetweetsCount
string
Retweets.
✓
✓
✓
twitterQuotesCount
string
Quote tweets.
✓
✓
✓
Per-media video metrics. Each is an array indexed by media position in the post; null entries mark non-video media.
twitterPerMediaVideoViewsCount
(string | null)[]
Video views per media item.
✓
✓
twitterPerMediaVideoPlaybackStartCount
(string | null)[]
Playbacks started per media item.
✓
✓
twitterPerMediaVideoPlayback25Count
(string | null)[]
Playbacks reaching 25% per media item.
✓
✓
twitterPerMediaVideoPlayback50Count
(string | null)[]
Playbacks reaching 50% per media item.
✓
✓
twitterPerMediaVideoPlayback75Count
(string | null)[]
Playbacks reaching 75% per media item.
✓
✓
twitterPerMediaVideoPlaybackCompleteCount
(string | null)[]
Playbacks completed per media item.
✓
✓
Bluesky
Post-level metrics.
blueskyRepostsCount
string
Reposts.
✓
✓
✓
blueskyQuotesCount
string
Quote posts.
✓
✓
✓
Threads
Post-level metrics.
threadsRepostsCount
string
Reposts.
✓
✓
✓
threadsQuotesCount
string
Quote posts.
✓
✓
✓
Post-level metrics.
facebookPostMediaViewsCount
string
Media views on the post.
✓
✓
facebookPostMediaViewsUniqueCount
string
Unique media views on the post.
✓
✓
facebookPostReactionsByType
object
Reactions broken down by type (e.g. like, love, haha).
✓
✓
Video and Reels metrics.
facebookBlueReelsPlaysCount
string
Reel plays.
✓
✓
facebookFbReelsReplaysCount
string
Reel replays.
✓
✓
facebookFbReelsTotalPlaysCount
string
Total reel plays (plays plus replays).
✓
✓
facebookPostVideoWatchTimeMsAvg
string
Average video watch time, milliseconds.
✓
✓
facebookPostVideoFollowersCount
string
Followers gained from the video.
✓
✓
facebookPostVideoLikesByReactionType
object
Video likes broken down by reaction type.
✓
✓
facebookPostVideoSocialActionsByType
object
Video social actions broken down by type.
✓
✓
facebookPostVideoViewTimeMsSum
string
Total video view time, milliseconds.
✓
✓
facebookTotalVideoViewsCount
string
Total video views.
✓
✓
facebookTotalVideoViewsUniqueCount
string
Unique video views.
✓
✓
facebookTotalVideoViewsAutoplayedCount
string
Autoplayed video views.
✓
✓
facebookTotalVideoViewsClickedToPlayCount
string
Click-to-play video views.
✓
✓
facebookTotalVideoViewsSoundOnCount
string
Video views with sound on.
✓
✓
facebookTotalVideoCompleteViewsCount
string
Complete video views.
✓
✓
facebookTotalVideoCompleteViewsUniqueCount
string
Unique complete video views.
✓
✓
facebookTotalVideoCompleteViewsAutoplayedCount
string
Autoplayed complete video views.
✓
✓
facebookTotalVideoCompleteViewsClickedToPlayCount
string
Click-to-play complete video views.
✓
✓
facebookTotalVideoCompleteViewsOrganicCount
string
Organic complete video views.
✓
✓
facebookTotalVideoCompleteViewsOrganicUniqueCount
string
Unique organic complete video views.
✓
✓
facebookTotalVideoCompleteViewsPaidCount
string
Paid complete video views.
✓
✓
facebookTotalVideoCompleteViewsPaidUniqueCount
string
Unique paid complete video views.
✓
✓
facebookTotalVideoViews10sCount
string
Video views of at least 10 seconds.
✓
✓
facebookTotalVideoViews10sUniqueCount
string
Unique 10-second video views.
✓
✓
facebookTotalVideoViews10sAutoplayedCount
string
Autoplayed 10-second video views.
✓
✓
facebookTotalVideoViews10sClickedToPlayCount
string
Click-to-play 10-second video views.
✓
✓
facebookTotalVideoViews10sOrganicCount
string
Organic 10-second video views.
✓
✓
facebookTotalVideoViews10sPaidCount
string
Paid 10-second video views.
✓
✓
facebookTotalVideoViews10sSoundOnCount
string
10-second video views with sound on.
✓
✓
facebookTotalVideoViews15sCount
string
Video views of at least 15 seconds.
✓
✓
facebookTotalVideoViews60sExcludesShorterCount
string
Video views of at least 60 seconds (excludes shorter).
✓
✓
facebookTotalVideoWatchTimeMsAvg
string
Average total video watch time, milliseconds.
✓
✓
facebookTotalVideoViewTimeMsSum
string
Total video view time, milliseconds.
✓
✓
facebookTotalVideoViewTimeOrganicMsSum
string
Organic video view time, milliseconds.
✓
✓
facebookTotalVideoViewTimePaidMsSum
string
Paid video view time, milliseconds.
✓
✓
facebookTotalVideoStoriesByActionType
object
Video stories (shares/comments/etc.) broken down by action type.
✓
✓
facebookTotalVideoReactionsByType
object
Video reactions broken down by type.
✓
✓
facebookTotalVideoViewTimeMsByAgeBucketAndGender
object
Video view time broken down by age bucket and gender.
✓
✓
facebookTotalVideoViewTimeMsByRegionId
object
Video view time broken down by region.
✓
✓
facebookTotalVideoViewsByDistributionType
object
Video views broken down by distribution type.
✓
✓
Post-level metrics.
linkedinFirstLevelCommentsCount
string
First-level comments (excludes replies).
✓
✓
✓
linkedinReactionsByType
object
Reactions broken down by type (e.g. like, praise, empathy).
✓
✓
Post-level metrics.
pinterestPinClicksCount
string
Pin clicks.
✓
✓
pinterestReactionsCount
string
Reactions.
✓
✓
✓
pinterestVideoP95ViewsCount
string
Video views reaching 95% of the video.
✓
✓
pinterestVideo10sViewsCount
string
Video views of at least 10 seconds.
✓
✓
pinterestVideoMrcViewsCount
string
MRC-standard video views.
✓
✓
pinterestVideoV50WatchTimeMsSum
string
Watch time for views past 50%, milliseconds.
✓
✓
pinterestSaveRate
number
Saves divided by impressions, a 0–1 ratio.
✓
✓
YouTube
YouTube metrics come from the YouTube Analytics API, which reports only finalized views after YouTube filters spam and invalid traffic. viewsCount for a YouTube post therefore reads lower than the count on the YouTube watch page, and the gap narrows as YouTube finalizes more data. See: Analytics.
Post-level metrics.
youtubeDislikesCount
string
Dislikes.
✓
✓
youtubeSubscribersLostCount
string
Subscribers lost from the video.
✓
✓
youtubeVideosAddedToPlaylistsCount
string
Times the video was added to a playlist.
✓
✓
youtubeVideosRemovedFromPlaylistsCount
string
Times the video was removed from a playlist.
✓
✓
youtubeRedViewsCount
string
YouTube Premium (Red) views.
✓
✓
youtubeRedViewTimeMsSum
string
YouTube Premium (Red) watch time, milliseconds.
✓
✓
youtubeEngagedViewsCount
string
Engaged views.
✓
✓
youtubeAverageViewPercentage
number
Average percentage of the video watched, 0–100.
✓
✓
youtubeCardClicksCount
string
Card clicks.
✓
✓
youtubeCardImpressionsCount
string
Card impressions.
✓
✓
youtubeCardClickRate
number
Card clicks divided by impressions, a 0–1 ratio.
✓
✓
youtubeCardTeaserClicksCount
string
Card teaser clicks.
✓
✓
youtubeCardTeaserImpressionsCount
string
Card teaser impressions.
✓
✓
youtubeCardTeaserClickRate
number
Card teaser clicks divided by impressions, a 0–1 ratio.
✓
✓
youtubeAnnotationClicksCount
string
Annotation clicks.
✓
✓
youtubeAnnotationClickableImpressionsCount
string
Clickable annotation impressions.
✓
✓
youtubeAnnotationClosesCount
string
Annotation closes.
✓
✓
youtubeAnnotationClosableImpressionsCount
string
Closable annotation impressions.
✓
✓
youtubeAnnotationImpressionsCount
string
Annotation impressions.
✓
✓
youtubeAnnotationClickThroughRate
number
Annotation click-through rate, a 0–1 ratio.
✓
✓
youtubeAnnotationCloseRate
number
Annotation close rate, a 0–1 ratio.
✓
✓
Related
Analytics — the two endpoints that return these metrics.
List Top Performing Posts —
GET /v2/analyticsGet Post Analytics —
GET /v2/posts/{id}/analytics
Comments /v2/comments
Blotato allows you to read and post comments on your published Instagram posts and Facebook Page posts. Twitter/X, TikTok, LinkedIn, Pinterest, Threads, Bluesky, and YouTube are not supported at this time. Three endpoints let you list, read, and post comments:
List Comments —
GET /v2/commentsGet Comment —
GET /v2/comments/:commentIdPost Comment —
POST /v2/comments
Comments are available on all paid plans.
To manage Instagram and Facebook comments in the Blotato web app, see Comments and Messaging Inbox.
Blotato does not backfill comments. It starts capturing comments once your account has comments enabled and you connect or reconnect your account. Comments left before then do not appear in these endpoints.
Blotato retains comments for up to 45 days. Comments older than 45 days are not available through these endpoints.
The /comments endpoints cover two directions:
Inbound comments your audience leaves on your posts. These have
isAuthor: false.Outbound comments you post through Blotato. These have
isAuthor: true.
The comments API lists and posts top-level comments and one level of replies. You can reply to a top-level comment on your post, but you cannot reply to a reply.
Before You Start
Blotato must have permissions to read and post comments on your account before you can use the Blotato comments endpoints.
If you connected your account before comments launched, reconnect it so Blotato has the new permission.
For Instagram, see Connect Instagram.
For Facebook, see Connect Facebook.
List Comments
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /comments
Method: GET
Description
Returns your comments across connected accounts, ordered by creation time (most recent first). Use cursor-based pagination and the optional filters below.
Query Parameters
limit
integer
No
Maximum comments to return (1-250). Default 50.
cursor
string
No
Cursor from a previous response. Pass it to fetch the next page.
platform
array
No
Filter by platform. Values: instagram, facebook.
accountId
string
No
Filter to a single connected account.
parentCommentId
string
No
Filter to direct replies to a single comment.
postId
string
No
Filter to comments on a single post using its Blotato post ID.
since
string
No
Only include comments created on or after this ISO 8601 timestamp.
until
string
No
Only include comments created on or before this ISO 8601 timestamp.
Response
Status Code: 200 OK
cursor
string
Cursor for the next page. Absent when there are no more comments.
Get Comment
Endpoint
URL: /comments/:commentId
Method: GET
Description
Fetches a single comment by its Blotato ID. The comment is an inbound reply from your audience or an outbound comment you posted through Blotato.
Path Parameters
commentId
string
Yes
Blotato ID of the comment.
Response
Status Code: 200 OK
Returns a Comment Object.
Post Comment
Endpoint
URL: /comments
Method: POST
Description
Posts a comment on one of your published posts, or a reply to an existing top-level comment when you pass parentCommentId. Blotato queues the comment and posts it in the background, so the response returns status queued. Poll Get Comment with the returned id to confirm the comment reached posted or failed.
Request Body
postId
string
Yes
Blotato ID of the published post to comment on. For a reply, use the parent comment's non-null postId. Otherwise, use List Posts, from items whose state.type is published. Do not substitute the social platform's post ID.
text
string
Yes
Plain-text comment body. Instagram allows up to 2200 characters, Facebook up to 8000.
parentCommentId
string
No
Blotato ID of a top-level, posted comment on the same post to reply to. Replies to replies are not supported.
Response
Status Code: 201 Created
Returns a Comment Object with status queued.
Errors
404
The published post or parent comment was not found, or comments are not enabled for your account.
422
The post's platform does not support comments, the comment exceeds the platform's character limit, the parent comment is invalid, Blotato lacks the Instagram comment permission (error code 20203), or you reached your monthly active-contacts limit (error code 20101).
429
Rate limit exceeded (30 requests per minute).
Replies and Your Contacts Limit
Replying to a comment from your audience counts the person as an active contact for the month. Your current account limit controls how many active contacts you reach. When you pass the limit, Post Comment returns 422 with error code 20101. Replying to your own comment does not count.
See Active Contacts for the definition, standard plan limits, and how to check your current limit.
Comment Object
id
string
Blotato comment ID.
accountId
string
ID of the connected account the comment belongs to.
platform
string
instagram or facebook.
postId
string or null
Blotato ID of the tracked post. An incoming Instagram comment also creates this ID for posts published outside Blotato. A populated ID does not prove Blotato published the post.
parentCommentId
string or null
Blotato ID of the parent comment when this comment is a reply. null for top-level comments.
platformPostId
string
Social platform (e.g. Instagram) ID of the parent post.
platformCommentId
string or null
Social platform (e.g. Instagram) ID of the comment.
authorId
string or null
Social platform (e.g. Instagram) ID of the comment author.
isAuthor
boolean
true when your connected account authored the comment. false for an audience reply.
text
string
Comment text.
errorMessage
string or null
Set only when status is failed.
createdAt
string
ISO 8601 timestamp when the comment was created.
Status Values
queued
Accepted and waiting to post.
processing
Posting to the social platform.
posted
Live on the social platform.
failed
Did not post. See errorMessage.
deleted
Removed from the social platform.
Rate Limits
GET /comments
60 / min
GET /comments/:commentId
60 / min
POST /comments
30 / min
Messages /v2/messages
Blotato allows you to read and send direct messages on your Instagram account and Facebook Page. Twitter/X, TikTok, LinkedIn, Pinterest, Threads, Bluesky, and YouTube are not supported at this time. Five endpoints let you list conversations, read a conversation, list messages, read a message, and send a message:
List Conversations —
GET /v2/conversationsGet Conversation —
GET /v2/conversations/:conversationIdList Messages —
GET /v2/messagesGet Message —
GET /v2/messages/:messageIdSend Message —
POST /v2/messages
Messages are available on all paid plans.
To manage Instagram and Facebook conversations in the Blotato web app, see Comments and Messaging Inbox.
To send automatic replies after a comment or incoming message, use DM Automations. You manage these automations in the web app or through an AI tool connected to Blotato MCP.
Each message has a direction:
Incoming messages your contacts send you. These have
direction: "incoming".Outgoing messages you send through Blotato. These have
direction: "outgoing".
You reply to people who already have a conversation with you. You send to a recipientId taken from an existing conversation or an incoming message, not to an arbitrary user. The social platform limits who you can message and when. See Messaging Windows.
Blotato retains messages for up to 45 days. Messages older than 45 days are not available through these endpoints.
Before You Start
Blotato must have permissions to read and send messages on your account before you can use the Blotato messaging endpoints.
If you connected your account before messaging launched, reconnect it so Blotato has the new permission.
For Instagram, see Connect Instagram.
For Facebook, see Connect Facebook.
List Conversations
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /conversations
Method: GET
Description
Returns your conversations across connected accounts, ordered by most recent activity. Use cursor-based pagination and the optional filters below.
Query Parameters
limit
integer
No
Maximum conversations to return (1-250). Default 50.
cursor
string
No
Cursor from a previous response. Pass it to fetch the next page.
platform
string
No
Filter by platform. Values: instagram, facebook.
accountId
string
No
Filter to a single connected account.
Response
Status Code: 200 OK
cursor
string
Cursor for the next page. Absent when there are no more conversations.
Get Conversation
Endpoint
URL: /conversations/:conversationId
Method: GET
Description
Fetches a single conversation by its Blotato ID.
Path Parameters
conversationId
string
Yes
Blotato ID of the conversation.
Response
Status Code: 200 OK
Returns a Conversation Object.
List Messages
Endpoint
URL: /messages
Method: GET
Description
Returns your messages across connected accounts, ordered by creation time (most recent first). Use cursor-based pagination and the optional filters below.
Query Parameters
limit
integer
No
Maximum messages to return (1-250). Default 50.
cursor
string
No
Cursor from a previous response. Pass it to fetch the next page.
conversationId
string
No
Filter to messages in a single conversation.
platform
array
No
Filter by platform. Values: instagram, facebook.
accountId
string
No
Filter to a single connected account.
Response
Status Code: 200 OK
cursor
string
Cursor for the next page. Absent when there are no more messages.
Get Message
Endpoint
URL: /messages/:messageId
Method: GET
Description
Fetches a single message by its Blotato ID. Poll this after Send Message to check whether an outgoing message reached sent or failed.
Path Parameters
messageId
string
Yes
Blotato ID of the message.
Response
Status Code: 200 OK
Returns a Message Object.
Send Message
Endpoint
URL: /messages
Method: POST
Description
Sends a direct message to one recipient. Blotato queues the message and sends it in the background, so the response returns status queued. Poll Get Message with the returned id to confirm the message reached sent or failed.
Send to a recipientId taken from an existing conversation or an incoming message. The social platform limits who you can message and when. See Messaging Windows.
Request Body
accountId
string
Yes
Blotato ID of the connected account the message is sent from.
recipientId
string
Yes
Social platform (e.g. Instagram) ID of the recipient. Get it from an existing conversation or incoming message.
text
string
Yes
Plain-text message body. Instagram messages are limited to 1000 bytes, Facebook to 2000 characters. With buttons attached, the limit drops to 640 characters. See Buttons and Quick Replies.
Target
targetType
string
Yes
Value: instagram or facebook.
pageId
string
For Facebook
ID of the Facebook Page to send from, from subaccounts. Required when targetType is facebook.
commentId
string
No
Blotato comment ID. When set, Blotato delivers the message as a private reply to that comment instead of a direct message.
attachment
object
No
Up to 3 call-to-action buttons pinned under the message. See Buttons and Quick Replies.
quickReplies
array
No
Up to 13 tappable reply chips shown under the message. See Buttons and Quick Replies.
responseType
string
No
How the message fits the platform's messaging window: RESPONSE, UPDATE, or MESSAGE_TAG. Default RESPONSE. See Messaging Windows.
tag
string
No
Required when responseType is MESSAGE_TAG (e.g. HUMAN_AGENT).
Buttons and Quick Replies
Facebook and Instagram support buttons and quick replies in direct messages. Set target.attachment for buttons, or target.quickReplies for chips. The two are mutually exclusive: a request carrying both is rejected with 422.
For any platform-applied limitations, see:
Buttons
Buttons sit under the message and stay there. Up to 3 buttons are supported.
Instagram Limitation: Instagram only renders buttons in the Instagram mobile app. A recipient reading the conversation on instagram.com in a desktop browser sees the message text with no buttons.
Send an attachment or a URL inside text, not both. A message carrying both leaves the URL in text unclickable on desktop, so a desktop recipient ends up with no working link. For a primarily desktop audience, drop the attachment and put the URL in text.
type
string
Yes
Value: button.
buttons
array
Yes
1 to 3 buttons.
Each button has:
type
string
Yes
web_url opens a link. postback reports the tap back to you.
title
string
Yes
Button label, 1 to 20 characters.
url
string
For web_url
Link the button opens. Starts with https://.
payload
string
For postback
Value echoed back on tap, 1 to 1000 characters.
With buttons set, text is required and limited to 640 characters.
Quick Replies
Quick replies are tappable chips offered as canned answers. They disappear once the person taps one or types their own message. Pass 1 to 13.
title
string
Yes
Chip label, 1 to 20 characters.
payload
string
Yes
Value echoed back on tap, 1 to 1000 characters.
Quick replies require non-empty message text.
Reading a Tap
A quick-reply tap and a postback tap both arrive as the next incoming message carrying payload.selection, but they reach you differently.
Quick replies send a real text message. text holds the chip label, adn Blotato attaches payload.selection alongside it.
Postbacks do not send a text message. Blotato records the tap as an incoming message, sets text to the button label, and attaches payload.selection.
selection.type
quick-reply
The person tapped a chip. text is the chip label.
selection.type
postback
The person tapped a button you attached. text is the button label.
selection.payload
string or null
The payload received with the tap. A postback is null when the platform webhook supplies no payload. Creating a postback button through this API requires a payload of 1–1000 characters.
Branch on selection.payload, not on text. Two chips that share a label are distinguishable only by their payload.
A web_url button produces no selection. The link opens and nothing comes back.
Blotato subscribes your account to the postback webhook when you connect it. If you connected your account before buttons were launched, reconnect to start receiving postback events. Quick-reply taps need no reconnect.
Response
Status Code: 201 Created
Returns a Message Object with status queued.
Errors
Send Message returns 201 on success, 422 when the request is rejected, and 429 when you exceed 30 requests per minute.
Messaging is available on every plan, so there is no "not enabled" rejection, and this endpoint does not return 404. A connected account that is missing or expired surfaces after the message is queued, as a failed message.
A 422 means one of:
The message exceeds the platform's character limit. Instagram allows 1000 bytes, Facebook 2000 characters, and either drops to 640 characters when buttons are set.
You passed both
attachmentandquickReplies. Send one or the other.You set buttons or quick replies without message
text.The messaging window has closed.
The comment you are replying to is invalid, or it already received a private reply.
You reached your monthly active-contacts limit (error code 20101).
responseTypeisMESSAGE_TAGand you did not settag.
Message-send failures that happen after the message is queued do not return an error here. The message reaches status failed with an errorCode and errorMessage. See Messaging Errors.
Messaging Windows
The social platform limits who you can message and when. You reply to people who already have a conversation with you, not arbitrary users.
Standard window: send a
RESPONSEwithin 24 hours of the contact's last message.Private reply to a comment: set
commentIdon the target to reply once, within 7 days of the comment.Outside the window: set
responseTypetoMESSAGE_TAGwith an approvedtag(e.g.HUMAN_AGENT) to send a permitted follow-up.
These windows come from the social platform, not Blotato. A message sent outside an allowed window reaches status failed.
Sending a message to a new person also counts toward your monthly active-contacts limit. See Active Contacts.
Conversation Object
id
string
Blotato conversation ID.
accountId
string
ID of the connected account this conversation belongs to.
platform
string
instagram or facebook.
participants
array
The other people in the conversation. Each has id, name, username, and profileImageUrl, any of which may be null.
createdAt
string
ISO 8601 timestamp when the conversation started.
updatedAt
string
ISO 8601 timestamp of the most recent activity.
Message Object
id
string
Blotato message ID.
conversationId
string or null
Blotato ID of the parent conversation.
platform
string
instagram or facebook.
direction
string
incoming for messages you receive, outgoing for messages you send.
senderId
string or null
Social platform (e.g. Instagram) ID of the sender.
recipientId
string
Social platform (e.g. Instagram) ID of the recipient.
text
string
Message text.
errorMessage
string or null
Set only when status is failed.
createdAt
string
ISO 8601 timestamp when the message was created.
Payload
payload is null on a plain-text message. Otherwise it holds one or more of:
selection
object
Set on an incoming message where the person tapped a postback button or a quick reply. Holds type (postback or quick-reply) and your payload string. See Reading a Tap.
Status Values
An outgoing message you send moves through queued, processing, then sent, or failed if it does not go through. An incoming message you receive shows as delivered.
queued
Accepted and waiting to send.
processing
Sending to the social platform.
sent
Handed to the social platform.
delivered
An incoming message delivered to you.
failed
Did not send. See errorMessage.
Rate Limits
GET /conversations
60 / min
GET /conversations/:conversationId
60 / min
GET /messages
60 / min
GET /messages/:messageId
60 / min
POST /messages
30 / min
DM Automations /v2/dm-automations
A DM automation sends a direct message when someone comments on your post or sends you a message. Blotato supports DM automations on Instagram and Facebook Pages. Twitter/X, TikTok, LinkedIn, Pinterest, Threads, Bluesky, and YouTube are not supported at this time.
Nine endpoints let you manage automations and inspect their activity:
List DM Automations —
GET /v2/dm-automationsGet DM Automation —
GET /v2/dm-automations/:idCreate DM Automation —
POST /v2/dm-automationsUpdate DM Automation —
PATCH /v2/dm-automations/:idUpdate DM Automation Trigger —
PATCH /v2/dm-automations/:flowId/triggers/:triggerIdDelete DM Automation —
DELETE /v2/dm-automations/:idList Runs —
GET /v2/dm-automations/:id/runsList Logs —
GET /v2/dm-automations/:id/logsGet Analytics —
GET /v2/dm-automations/:id/analytics
For the web app walkthrough, see DM Automations.
Before You Start
Blotato needs permission to read comments and read and send messages on your account.
If you connected your account before comments, messaging, or (for Instagram) follow gating launched, reconnect it so Blotato has the new permissions.
For Instagram, see Connect Instagram.
For Facebook, see Connect Facebook.
For Instagram comment triggers, the connected Instagram account must own the post. DM automations do not run on posts where your account appears only as a collaborator. If you co-authored a post, create the automation under the Instagram account that originally published the post.
How an Automation Runs
Someone comments on your post or sends your account a message.
Blotato matches the event against every active trigger on every live automation on the account.
A match starts one run per matching automation. An automation with a comment trigger and a message trigger starts a single run per event.
If the automation has a follow gate or email gate, Blotato waits for the contact to complete it. On automations published after September 14, 2026, a contact with an email already on file skips the email gate.
Blotato sends the DM, then calls the webhook if one is configured.
The run reaches
completed,failed,expired, orsuperseded.
Every live automation whose trigger matches starts its own run. Two automations matching the same comment both try to answer it, one reply reaches the contact, and the other run fails. Two automations matching the same message both send. Each matching comment also starts a new run, so a contact who comments the keyword twice gets two replies.
A comment trigger answers with a private reply to the comment. A message trigger answers with a standard DM.
Your own comments and the messages your account sends never start a run.
Comments on Instagram collaborator posts do not start a run for the collaborator account. Use the owner account for the automation.
Testing a Comment Trigger
Test from a different Instagram or Facebook account. A comment posted by the same account connected to the automation is skipped, even when its text matches a trigger keyword.
Optional Steps
Set followGate, emailGate, or webhook to extend the run. Blotato runs the steps in a fixed order:
Follow gate (
followGate, Instagram only). Sends the gate message with a confirm button, waits up to 30 days for a reply, then checks whether the contact follows the account. A contact who does not follow gets the gate message again.Email gate (
emailGate). Sends the gate message, waits up to 72 hours for a reply, and reads the first email address out of it. A reply holding no email address returns the gate message. A match saves to the contact. On automations published after September 14, 2026, a contact with an email already on file skips the gate. See Email Gate Object.Your message (
dmMessageplusbuttons).Webhook (
webhook). Calls your endpoint after the message sends.
A run waiting on a gate reaches expired when the contact never answers inside the window, and superseded when a newer run starts waiting on the same contact.
While a run waits on a contact's reply, their next DM resumes the waiting run instead of starting a new run. A button tap never starts a run.
List DM Automations
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /dm-automations
Method: GET
Description
Returns your DM automations, ordered by creation time (most recent first). Use cursor-based pagination. Archived automations do not appear. Every item includes run counts from the last 24 hours and the time it last ran.
Query Parameters
limit
integer
No
Maximum automations to return (1-250). Default 50.
cursor
string
No
Cursor from a previous response. Pass it to fetch the next page.
Response
Status Code: 200 OK
items[].stats
object
Run counts from the last 24 hours: triggered, completed, and failed, plus lastRunAt.
items[].stats.lastRunAt
string or null
ISO 8601 time the automation last ran. Null when it has never run.
cursor
string
Cursor for the next page. Absent when there are no more automations.
For all-time totals and failures from the last 7 days, use Get Analytics.
Get DM Automation
Endpoint
URL: /dm-automations/:id
Method: GET
Description
Fetches a single automation by its Blotato ID, including its triggers and message. An archived automation still returns here with isActive: false.
Path Parameters
id
string
Yes
Blotato ID of the automation.
Response
Status Code: 200 OK
The flow object is a DM Automation Object.
Create DM Automation
Endpoint
URL: /dm-automations
Method: POST
Description
Creates a DM automation. When any of its triggers fires, the automation sends one direct message: text plus up to 3 link buttons. Pass up to 2 triggers in triggers: one comment-received trigger and one message-received trigger. One matching comment or message starts a single run. Optional fields gate the message behind an Instagram follow check, ask for an email address first, or call a webhook after the message sends.
Set
followGate(Instagram only) to gate the message behind a follow check.Set
emailGateto gate it behind the contact replying with an email address.Set
webhookto call an external endpoint once the message sends.
An automation is created as a draft unless you pass isActive: true. Inspect existing flows before creating another. Keep the example inactive until the user requests activation and approves the account, trigger scope, message, and link. Include only the requested triggers and optional steps.
Request Body
Response
Status Code: 201 Created
Update DM Automation
Endpoint
URL: /dm-automations/:id
Method: PATCH
Description
Updates an automation. Each field present in the patch replaces that field. Omitted fields stay unchanged. triggers replaces the whole trigger set, and [] clears it. Pass null for followGate, emailGate, or webhook to remove it.
The connected account, platform, and target are fixed at creation. To run on a different account, create a new automation.
Request Body
The patch is nested under a patch key.
name
string
No
New automation label, 1-60 characters.
triggers
array
No
Replaces every trigger. Up to 2 triggers, at most one per type. Pass [] to remove every trigger. See Trigger Object.
dmMessage
string
No
Replaces the message text, 1-640 characters.
buttons
array
No
Replaces the buttons. Pass [] to remove every button.
followGate
object or null
No
Replaces the follow gate. Pass null to remove it. Instagram only. See Follow Gate Object.
isActive
boolean
No
true publishes the automation. false moves it to draft. Omit to keep the current state.
Content changes to a live automation publish as soon as the request succeeds. Content changes to a draft stay saved until you pass isActive: true. A run already in progress keeps the version it started with.
A live automation needs at least one active trigger. To clear every trigger, pass an empty triggers array and set isActive: false in the same request. To remove one trigger, pass triggers holding the trigger you keep. To update a single trigger without other changes, for example to turn it off, use Update DM Automation Trigger.
Updating an automation's content or triggers reissues its trigger IDs. Read triggers from the response before you call Update DM Automation Trigger.
Response
Status Code: 200 OK
Update DM Automation Trigger
Endpoint
URL: /dm-automations/:flowId/triggers/:triggerId
Method: PATCH
Description
Updates a single trigger on an automation, for example to turn it on or off. The change applies immediately on a live automation, with no republish. The other triggers, the message, and the optional steps stay as they are.
Read the trigger ID from the triggers array of the automation. Updating an automation's content or triggers reissues its trigger IDs, so fetch the automation again before you update a trigger.
Path Parameters
flowId
string
Yes
Blotato ID of the automation.
triggerId
string
Yes
ID of the trigger, from the automation's triggers array.
Request Body
The patch is nested under a patch key.
isActive
boolean
Yes
true turns the trigger on. false turns it off.
A live automation needs at least one active trigger. Turning off its last active trigger returns 422 with error code 20303. To stop every trigger, move the automation to draft with Update DM Automation.
A draft accepts any update. Blotato checks the active-trigger rule when you publish.
Response
Status Code: 200 OK
The trigger object is a Trigger Object. A 404 means the automation or the trigger ID was not found.
Delete DM Automation
Endpoint
URL: /dm-automations/:id
Method: DELETE
Description
Archives an automation and stops new runs. Existing runs, including waiting gates, remain able to continue. Archiving does not cancel messages already queued. Archive only when the user requests it.
The archived automation leaves List DM Automations, but Get DM Automation still returns it. Publishing it again with Update DM Automation and isActive: true restores it.
Response
Status Code: 200 OK
Returns the archived DM Automation Object.
List Runs
Endpoint
URL: /dm-automations/:id/runs
Method: GET
Description
Returns the execution runs of one automation, ordered by activity time (most recent first). Use this endpoint to confirm an automation fired and inspect failed runs.
Query Parameters
limit
integer
No
Maximum runs to return (1-250). Default 50.
cursor
string
No
Cursor from a previous response. Pass it to fetch the next page.
status
string[]
No
Include runs matching any supplied status: running, waiting, completed, expired, superseded, or failed. Omit to include every status.
since
string
No
Include runs with activity at or after this ISO 8601 timestamp.
Response
Status Code: 200 OK
See Run Object.
List Logs
Endpoint
URL: /dm-automations/:id/logs
Method: GET
Description
Returns logs written as an automation's runs progress, ordered by creation time (most recent first). Pass flowRunId to narrow the response to one run.
Query Parameters
flowRunId
string
No
Include logs belonging to this run. Omit to include logs across every run.
limit
integer
No
Maximum logs to return (1-250). Default 50.
cursor
string
No
Cursor from a previous response. Pass it to fetch the next page.
Response
Status Code: 200 OK
See Log Object.
Get Analytics
Endpoint
URL: /dm-automations/:id/analytics
Method: GET
Description
Returns all-time run totals and the number of recent failures for one automation.
Response
Status Code: 200 OK
triggered
integer
Runs started by a matching comment or message.
completed
integer
Runs where every step finished.
failed
integer
All-time runs ending on an error.
issues
integer
Runs that failed during the last 7 days. This is a subset of failed.
Runs still in progress and runs ending as expired or superseded count toward triggered, but not completed or failed. The sum of completed and failed is sometimes lower than triggered.
DM Automation Object
id
string
Blotato automation ID.
accountId
string
ID of the connected account the automation runs on.
name
string
Automation label.
platform
string
instagram or facebook.
triggers
array
Triggers the automation listens for, up to 2. Empty on a draft with no triggers. See Trigger Object.
dmMessage
string
Message text sent when a trigger fires.
followGate
object
Follow gate on the automation. Absent when no follow gate is set. See Follow Gate Object.
emailGate
object
Email gate on the automation. Absent when no email gate is set. See Email Gate Object.
isActive
boolean
true when the automation is live and listening.
publishedVersionId
string or null
ID of the published version. null for a draft.
createdAt
string
ISO 8601 timestamp when the automation was created.
updatedAt
string
ISO 8601 timestamp of the most recent edit.
Target
targetType
string
Yes
instagram or facebook.
pageId
string
For Facebook
ID of the Facebook Page, from subaccounts. Required when targetType is facebook.
Trigger Object
An automation holds up to 2 triggers: one comment-received trigger and one message-received trigger. Each trigger carries its own keywords, and a comment trigger carries its own postId. One matching comment or message starts a single run.
id
string
Read-only
Blotato trigger ID. Present on every trigger Blotato returns. Omit it when you create or update an automation. Pass it to Update DM Automation Trigger.
type
string
Yes
comment-received or message-received.
keywords
array
Yes
Words or phrases the comment or message must contain. Pass [] to fire on every comment or text message. A message without text, such as a photo or sticker, never fires.
postId
string or null
No
Comment triggers only. Blotato ID of the tracked post to match. Do not use the platform's native post ID. null watches every post and reel on the account.
isActive
boolean
No
false turns this trigger off while the automation stays live. Default true.
Blotato enforces these rules when an automation goes live and while it stays live:
At least one active trigger.
At most one trigger per type.
A draft holds any trigger set, including an empty one. Blotato rejects a request with more than 2 triggers.
Updating an automation's content or triggers reissues its trigger IDs. Read triggers from the response before you update a trigger.
Keyword matching ignores case, matches anywhere in the text, and tolerates line breaks inside a multi-word keyword. For example, price matches both price and pricey. A comment or message fires the automation when it contains any one of the keywords.
The trigger matches a Blotato post ID, not publication origin. List Published Posts and the web post picker list Blotato-published posts only. For an Instagram post published outside Blotato, an incoming comment creates a tracked post record. Retrieve the comment through List Comments, verify its account and native platformPostId, and use its non-null postId for the trigger. The request still needs the connected account and platform containing this post.
If the required Blotato post ID is unavailable, stop and explain the missing ID. Do not replace it with a native ID or widen a single-post request to all posts. Use postId: null with a keyword only when the user approves matching across the account's posts and reels.
Button Object
type
string
Yes
url. Link buttons are the only type buttons accepts.
title
string
Yes
Button label, up to 20 characters.
url
string
Yes to publish
http(s) URL the button opens.
To send quick-reply chips or postback buttons, use Send Message.
Instagram renders buttons in the Instagram mobile app only. A recipient reading the DM on instagram.com in a desktop browser sees the message text with no buttons. To work around this issue, you can add the URL directly to the message text, and Instagram will render it as a clickable link. Set buttons or put a URL inside dmMessage, not both, since a message carrying both leaves the URL unclickable on desktop. For a desktop audience, pass buttons: [] and put the URL in dmMessage. See Instagram Limitations.
Follow Gate Object
Instagram only. Holds dmMessage back until the contact follows the account.
message
string
Yes
Gate message text, 1-640 characters. Blotato sends it with a confirm button under it.
buttonTitle
string
No
Label on the confirm button, up to 20 characters. Default I'm following.
Blotato sends the gate message, waits up to 30 days for a reply, then reads the contact's follower status. A contact who follows receives dmMessage. A contact who does not receives the gate message again.
The gate message always goes first. Instagram grants access to follower status once the contact opens a DM thread with the account, so the gate message precedes the check.
An unknown follower status sends
dmMessage. Instagram withholds follower status for a contact who never granted profile access, and Blotato proceeds rather than blocking them.A confirmed follow lasts 30 days. The gate message still goes out on every run. Blotato reuses a confirmed follow for 30 days, so a repeat contact's reply passes without a new check. A negative result is never reused.
The confirm button is a postback button Blotato manages. You set its label only. See Instagram Limitations.
Any text reply advances the gate. Blotato runs the follower check on the contact's next text DM, whatever it says. A photo, sticker, or voice note does not count. The tap is a shortcut, not a requirement.
The account needs a button-tap subscription. Blotato subscribes the account at connect time. An account connected before DM automations and follow gating landed does not reliably receive a tap, and runs reach
expired. Reconnect the account to fix it.Instagram renders the confirm button in the mobile app only. A contact reading on instagram.com in a desktop browser sees the gate message with nothing to tap. Write
messageto ask for a typed reply, for example "Reply FOLLOWING once you have", so a desktop audience still advances.
Email Gate Object
Holds dmMessage back until the contact replies with an email address.
message
string
Yes
Gate message text, 1-640 characters.
Blotato sends the gate message, waits up to 72 hours for a reply, and reads the first email address out of it. A reply holding no email address returns the gate message and Blotato waits again. A match saves to the contact and dmMessage sends.
A contact with an email already on file skips the gate. Blotato sends dmMessage without the gate message. An email lands on file when the contact replies with an address to any email gate on the same connected account.
This applies to automations published after September 14, 2026. An automation published earlier sends the gate message every time until you save it again. Pass its current triggers to Update DM Automation, or click Save and Publish in the web app.
Blotato checks the shape of the address, not whether the mailbox exists. Read a captured address through the Webhook Object.
Webhook Object
Endpoint Blotato calls after dmMessage sends.
method
string
Yes
GET, POST, PUT, PATCH, or DELETE.
url
string
Yes
Public http(s) endpoint, 1-2048 characters.
headers
object
No
String keys and string values sent with the request, for example an API key.
Every method except GET carries a JSON body with Content-Type: application/json. GET carries no body.
email
string or null
Email address on file for the contact, captured by an email gate. null when Blotato holds none.
isFollower
boolean or null
Follower status a follow gate last recorded for the contact. null when Blotato never checked.
Both keys are present on every request except GET, with or without a gate on the automation.
Address
The host must resolve to a public address. Private, loopback, link-local, and cloud metadata ranges return error code 20304.
Protocol
http and https only.
Redirects
Blotato does not follow them. Point the automation at the final URL.
Timeout
15 seconds. A timeout logs a warning with error code 20305, the run still completes, and Blotato does not retry the request.
Response body
Blotato reads the first 16 KB.
Error response
A non-2xx status gets logged with its status, and the run still completes.
Failure
A blocked address, a DNS failure, or a connection error fails the run with error code 20304.
Headers
Redacted from run logs. The URL and body appear in the logs, so send keys in a header, not in the URL.
This webhook is separate from the webhook publish target, which sends post content to your endpoint at publish time.
Run Object
contactId
string
Social platform ID of the person who triggered the run.
platform
string
instagram or facebook.
error
object
Set only when status is failed. Holds code, message, and, when available, action and details with recovery context.
createdAt
string
ISO 8601 timestamp when the run started.
updatedAt
string
ISO 8601 timestamp of the most recent run update.
Run Status Values
running
Executing a step.
waiting
Waiting for the DM to settle, or waiting on the contact to answer a gate.
completed
Every step finished, including the DM.
expired
The contact never answered a gate inside its window: 30 days for a follow gate, 72 hours for an email gate. A run also expires when its message never settles within 30 minutes. Nothing further sent.
superseded
A newer run started waiting on the same contact, so this one stopped.
failed
The run stopped on an error, either before or after the DM went out. Read error.
Log Object
id
string
Blotato log ID.
flowRunId
string
ID of the run this log belongs to.
nodeId
string or null
ID of the step the log came from. null for run-level entries.
level
string
info, warning, or error.
message
string
Description of the step.
context
object
Step-specific details, for example the message ID.
createdAt
string
ISO 8601 timestamp when the log was written.
Platform Rules
Instagram and Facebook set these rules, not Blotato. A message outside an allowed window reaches status failed on the run.
Comment trigger. Blotato answers with a private reply to the comment. Both platforms allow one private reply per comment, within 7 days of the comment. A comment that already received a private reply, through Blotato or another tool, rejects the second reply.
Message trigger. Blotato replies within 24 hours of the person's last message.
No cold outreach. An automation only answers people who comment or message first.
A reply during a gate continues the run. While a run waits on a contact's answer, their next DM resumes the waiting run instead of starting a new one. A button tap never starts a run.
See Messaging Windows.
Active Contacts
Every DM an automation sends counts toward your monthly active-contacts limit, the same as a message sent through Send Message. Reaching the same person twice in a month counts once.
See Active Contacts.
Errors
404
The automation was not found. Returned by Get DM Automation, Update DM Automation, Update DM Automation Trigger, and Delete DM Automation. Update DM Automation Trigger also returns it for an unknown trigger ID. An archived automation still returns 200 from Get, Update, and Delete.
422
The automation is invalid for publishing (error code 20303), or the connected account is missing (error code 5000). Setting followGate on a facebook automation returns 20303. So does a live automation with no trigger, two triggers of one type, or no active trigger.
500
Unexpected server error.
A webhook failure surfaces on the run, not on the request. A blocked address, a DNS failure, or a connection error fails the run with error code 20304. A timeout logs a warning with error code 20305, and the run still completes. See Error Reference.
Rate Limits
GET /dm-automations
60 / min
GET /dm-automations/:id
60 / min
POST /dm-automations
30 / min
PATCH /dm-automations/:id
30 / min
PATCH /dm-automations/:flowId/triggers/:triggerId
30 / min
DELETE /dm-automations/:id
30 / min
GET /dm-automations/:id/runs
60 / min
GET /dm-automations/:id/logs
60 / min
GET /dm-automations/:id/analytics
60 / min
Create Source /v2/source-resolutions-v3
Submit content for extraction and receive a source ID for polling.
Endpoint
Rate Limit: 30 requests / minute
Authentication
Include your Blotato API key in the request headers:
Source Types
youtube
url
Extract YouTube transcript (English captions only)
tiktok
url
Extract TikTok transcript (English captions only)
article
url
Extract article text from a web page
pdf
url
Extract text from a PDF
audio
url
Transcribe audio (mp3, wav, m4a, ogg, flac, aac)
twitter
url
Extract tweet content
text
text
Transform raw text content with optional AI instructions
perplexity-query
text
AI-powered web research query
Parameters
source.sourceType
string
Yes
One of: youtube, tiktok, article, pdf, audio, twitter, text, perplexity-query
source.url
string
Required for URL-based types
The URL to extract content from
source.text
string
Required for text and perplexity-query
Raw text or search query
customInstructions
string
No
AI instructions to transform extracted content
Examples
Extract YouTube Transcript
YouTube and TikTok transcript extraction reads English captions only. A non-English video, or a video with no captions, returns a failed status. For those videos, pass the transcript or a summary using sourceType: "text" instead.
Extract Article with Custom Instructions
AI Research Query
Transform Raw Text
Response
Use this ID with the Get Source endpoint to retrieve the extracted content.
n8n and Make.com
In n8n, select Source > Create.
Save the returned
id.Use Source > Get to check the saved ID until
statusiscompletedorfailed.Read
contentaftercompleted, or reportmessageafterfailed.
Follow the n8n polling instructions or the source-to-publication workflow.
For Make, follow the Make setup guide. Inspect the installed module's fields or use the async REST contract. n8n operation labels do not establish Make module labels.
Get Source /v2/source-resolutions-v3/:id
Retrieve extracted content by source ID.
Endpoint
Authentication
Include your Blotato API key in the request headers:
Parameters
id
string
Yes
The source resolution ID (UUID) from Create Source
Clean Transcript Option
cleanTranscript is not a REST query parameter or an MCP tool argument. The n8n Blotato node's Source > Get operation provides a local Clean Transcript option, enabled by default. It processes the returned content after the API request.
For REST or MCP, retrieve the completed content first, then remove transcript timestamps in your agent or workflow if requested. Do not send cleanTranscript to this endpoint expecting it to change the response.
Response
Processing (poll again)
Completed
Failed
Status Values
queued
Source submitted, waiting to process
processing
Extraction in progress
completed
Extraction successful, content available
failed
Extraction failed, check message field
Polling Pattern
Source extraction is asynchronous. After calling Create Source:
Wait at least 10 seconds
Call Get Source with the ID
If status is
queuedorprocessing, wait and retryIf status is
completed, use thecontentfieldIf status is
failed, check themessagefield
n8n and Make.com
In the official Blotato nodes:
Add a Blotato node
Select "Source" > "Get"
Pass in the source ID from "Create Source"
Add a Wait node of at least 10 seconds between status checks
The extracted content appears in the response
Visual Templates
Create images and videos using pre-built templates with the Create Visual API endpoint.
How to Use Templates
Choose a template from the categories below
Retrieve the template through
GET /v2/videos/templates.Copy its exact
idintotemplateId. Some IDs are UUIDs and others are paths. Do not shorten a path.Send a POST request to
/v2/videos/from-templateswithinputs: {}, aprompt, andrender: true.
Example Request
Use the prompt parameter to describe what you want. Set inputs to {}. AI fills in the template inputs automatically.
Use the exact returned template ID. For this quote-card template, use the full path below.
LLM-Friendly Reference
For LLM integrations, see API Reference for LLMs for a plain text reference with all endpoints and parameters.
Image Slideshows
For product images, see Product Scene Placement.
Create image slideshows with text overlays. Images uploaded or AI-generated.
/base/v2/image-slideshow/5903b592-1255-43b4-b9ac-f8ed7cbf6a5f/v1
inputs.slides (objects)
Slideshow
53cfec04-2500-41cf-8cc1-ba670d2c341a
inputs.slidePrompts (strings)
Slideshow
The AI Video with AI Voice template uses inputs.scenes, not either slideshow field. Inspect the selected template's inputs before building a manual request.
Quote Cards
Quote card carousels with various background styles.
/base/v2/quote-card/77f65d2b-48cc-4adb-bfbb-5bc86f8c01bd/v1
Slideshow
/base/v2/quote-card/f941e306-76f7-45da-b3d9-7463af630e91/v1
Slideshow
Tweet Cards
Twitter/X-style quote cards with minimal or photo/video backgrounds.
/base/v2/tweet-card/9714ae5c-7e6b-4878-be4a-4b1ba5d0cd66/v1
Slideshow
Tutorial Carousels
Step-by-step tutorial visuals with customizable styling.
/base/v2/tutorial-carousel/2491f97b-1b47-4efa-8b96-8c651fa7b3d5/v1
Slideshow
/base/v2/tutorial-carousel/e095104b-e6c5-4a81-a89d-b0df3d7c5baf/v1
Slideshow
Images with Text
Combine images and text overlays in various styles.
/base/v2/images-with-text/0ddb8655-c3da-43da-9f7d-be1915ca7818/v1
Slideshow
/base/v2/images-with-text/3ed4bb92-dbfe-45e6-9dc8-605b77f70506/v1
Video
Video Editor
Combine and edit video clips with titles, captions, and music.
/base/v2/combine-clips/c306ae43-1dcc-4f45-ac2b-88e75430ffd8/v1
Video
AI Videos
AI-powered video generation with voiceovers and narration.
/base/v2/ai-selfie-video/57f5a565-fd17-458b-be43-4a2d8ccaca75/v1
Video
AI Avatar
AI avatar videos with generated B-roll footage.
/base/v2/ai-avatar-broll/7c26a1cd-d5b3-42da-9c73-2413333873b3/v1
Video
AI-Generated Infographics (V1 Legacy)
AI-powered infographic templates that generate single images based on text descriptions. Each template applies a unique visual style to your content.
News and Media
Urban and Street
Education
Outdoor
Creative
Tech
Historical
Don't See a Template for Your Use Case?
Submit a support ticket and describe the type of visual you need. To submit a ticket, click the orange circle button inside Blotato.
Include the following in your request:
A description of the visual format you need (e.g., "listicle carousel with numbered items")
The platform you plan to post on (e.g., Instagram, TikTok, LinkedIn)
A link to an example of the format, if available
See Also
Create Visual /v2/videos/from-templates
Migrating from the Old API Format
If you are getting this error: body.textToImageModel must be object, body.imageToVideoModel must NOT be valid
Your workflow is using an outdated request format. The old POST /v2/videos/creations endpoint with textToImageModel and imageToVideoModel as string fields no longer works.
Switch to the template system using POST /v2/videos/from-templates:
Browse available templates at my.blotato.com/videos/new
In n8n or Make, replace the old node with the Blotato "Create Visual" node
Select your template from the dropdown (start with a carousel — it renders in seconds)
Open the Logs to inspect the exact JSON payload each template expects
Override inputs one by one to customize
For AI story videos, choose the template named "AI Video with AI Voice."
See also: n8n FAQ — textToImageModel and imageToVideoModel
Creating a Visual
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /videos/from-templates
Method: POST
Description
This endpoint creates a new visual (image or video) from a template. Templates define the structure and input parameters for generating visuals like slideshows, quote cards, tweet cards, and more.
You can provide input parameters manually, or use the optional prompt parameter to have AI automatically fill in the template inputs based on your description.
Brand Kit is opt-in. Send a nonempty prompt and useBrandKit: true to include brand context when generating template inputs. An omitted or null brandId uses the primary brand. Without these conditions, include the required brand instructions in your prompt. MCP does not expose the same brand fields. See Brand Kit.
Request
Request Body
templateId
string
✅
The ID of the template to use. Get available templates from the /v2/videos/templates endpoint.
inputs
object
✅
Template-specific input parameters. Structure depends on the selected template. Can be an empty object {} if using the prompt parameter.
isDraft
boolean
❌
Save as draft without rendering. Default: false.
prompt
string
❌
Optional natural language prompt to auto-fill template inputs using AI. When provided, AI interprets your description and fills in the inputs automatically. Any manually provided inputs take precedence over AI-generated values.
render
boolean
❌
Whether to render the visual immediately. Default: true.
title
string
❌
A human-readable title for the generated video.
useBrandKit
boolean
❌
Default: false. With a nonempty prompt, includes compiled brand context during template input generation. Requires a configured brand. See Brand Kit.
brandId
string | null
❌
Brand ID for prompt-based generation with useBrandKit enabled. Omitted or null selects the primary brand.
Getting Available Templates
To list all available templates and their input specifications:
The template list includes premade Blotato visual templates only. User-generated visual templates created or edited in the Blotato web app are not available in n8n, Make.com, MCP, or the /v2/videos/templates endpoint. Use a premade Blotato visual template from the dropdown or templates endpoint.
Query Parameters:
fields
string
Comma-separated list of fields to include. Use id,name,description,inputs to get full template details.
search
string
Case-insensitive text search in template name or description. Characters are matched literally. Ignored when id is supplied.
id
string
Optional template ID to get a specific template.
Inspect inputs without generating a visual
Template lookup is read-only. Do not execute a blank Create Visual request to learn the schema. Generation is a separate operation which consumes credits.
Send the REST lookup below.
Match the result to the requested output.
Retain its complete
id.Read its
inputsspecification for field names, nested types, defaults, allowed values, and limits.Build the creation request only after confirming those inputs and the user's authorization to generate.
Search matches text literally, without case sensitivity. For an exact lookup, pass the returned id instead. An empty items array means no matching template was returned. Do not guess another ID or submit an empty templateId.
With fields=id,name,description,inputs, the response includes the template's name.
These templates use different input structures:
scenes, each with script and mediaSource
slides, each with imageSource and optional textOverlay
slidePrompts, where each entry is an image prompt string
title and quotes, where each quote is a string
Changing templateId also requires checking the new template's input schema. slides, slidePrompts, and scenes are not interchangeable.
For an error such as scenes.0: missing object, compare the submitted value at the reported path with the selected template's specification. Increasing wait time does not fix an input-validation error.
Responses
Success Response
Status Code: 201 Created
Visual creation is scheduled on the queue. To check status, poll the Get Visual Status endpoint.
Response Body:
Error Responses
Not Found
Status Code: 404 Not Found
Too Many Requests
Visual creation has a user-level rate limit of 30 requests / minute.
Status Code: 429 Too many requests
Examples
1. Create a Visual Using AI Prompt (Recommended)
The easiest way to create visuals is using the prompt parameter. AI will interpret your description and fill in the template inputs automatically.
2. Create a Visual with Manual Inputs
You can also specify inputs manually for full control:
3. Combine Prompt with Manual Overrides
You can use prompt for most inputs while manually specifying certain values:
In this example, AI fills in the slides content, but textPosition and textColor use your manual values.
Available Templates
Browse all templates with parameters and examples in the Visual Templates catalog. You can also use the /v2/videos/templates endpoint to get the current list programmatically. Common templates include:
Image Slideshow
Create slideshows from images with text overlays
Instagram Carousel Slideshow
AI-generated image carousels from text prompts
Quote Card
Generate quote cards with stylized backgrounds
Tweet Card
Create visual cards from tweet-style content
Tutorial Carousel
Step-by-step tutorial visuals
AI Story Video
AI-generated story videos with narration
Combine Clips
Merge multiple video clips
Template Input Types
Templates use various input types:
text
Plain text string
"Hello world"
number
Numeric value
42
boolean
True/false
true
enum
Choice from predefined values
"top" | "center" | "bottom"
image
Image URL
"https://example.com/image.jpg"
video
Video URL
"https://example.com/video.mp4"
color
Hex color code
"#FF5733"
array
List of items
[{...}, {...}]
object
Nested object
{ "key": "value" }
Troubleshooting
AI video renders take up to 10-15 minutes. A long render is normal and does not mean the request failed. Keep polling until the status reads done or the response includes error. If error is set, generation has stopped and the status will not change again, even if status is not a final status. If your AI agent reports the render as stuck or failing without an error, nudge it to check the status again before retrying.
If you're still having trouble generating a visual, navigate to https://my.blotato.com/videos/<YOUR_VIDEO_ID> to view and manually edit it.
Polling for Status
After creating a visual, poll the Get Visual Status endpoint to check its status:
Status values (in order):
queueing- Waiting to be processedgenerating-script- AI is generating the scriptscript-ready- Script is ready, generating mediagenerating-media- Media is being generatedmedia-ready- Media is ready, exportingexporting- Final export in progressdone- Complete. UsemediaUrlorimageUrlsfrom the response.creation-from-template-failed- Generation failed
See Get Visual Status for full response details.
Get Visual Status /v2/videos/creations/:id
Check Visual Creation Status
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /videos/creations/:id
Method: GET
Description
Poll this endpoint to check the status of a visual creation. After submitting a request with Create Visual, use the returned id to track its progress. If the response includes error, generation has stopped and the status will not change again, even if status is not a final status.
Request
Path Parameters
id
string
Yes
The video/visual ID returned by Create Visual
Response
Status Code: 200 OK
Status Values
queueing
Request is queued. Keep polling.
generating-script
AI is generating the script. Keep polling.
script-ready
Script is ready, generating media. Keep polling.
generating-media
Media is being generated. Keep polling.
media-ready
Media is ready, exporting. Keep polling.
exporting
Final export in progress. Keep polling.
done
Complete. mediaUrl and/or imageUrls are available.
creation-from-template-failed
Creation failed.
If error is set, stop polling and report the error. For example, a visual can stay at script-ready with an error when AI media generation failed before export.
Response: Done (success)
mediaUrl: URL of the rendered video. Use this inmediaUrlswhen publishing.imageUrls: Array of image URLs (for slideshows/carousels). Use these inmediaUrlswhen publishing.
Response: In Progress
Response: Failed
Response: Stopped With Error
Polling Pattern
How Long It Takes
Most visuals finish within a few minutes. AI video renders take up to 10-15 minutes. A long render is normal and does not mean the request failed. Keep polling until the status reads done or the response includes error. Treat a visual as stopped when error is set, even if status is still script-ready. If the wait exceeds your execution window, save the visual ID and report its current status. Check the existing visual before submitting another create request. Creating another visual starts another job and uses credits.
Example
Error Response
Status Code: 404 Not Found
Delete Video /v2/videos/:id
Deleting a single video
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /videos/:id
Method: DELETE
Description
Delete the video. Useful for cleaning up old, unused videos.
Request
Request Params
The request path parameters must contain the following fields:
id
string
✅
Video ID
Responses
Success Response
Status Code: 204 No Content
The video has been deleted successfully.
Response Body:
Error Responses
Status Code: 500 Internal server error
Scheduled Posts /v2/schedules
Managing Scheduled Posts
Scheduled posts are created via Publish Post using scheduledTime or useNextFreeSlot. These endpoints let you list, inspect, update, and delete scheduled posts before they publish.
To manage the recurring time slots themselves (the calendar grid), see Weekly posting schedule.
List Scheduled Posts
Endpoint
Base URL: https://backend.blotato.com/v2
URL: /schedules
Method: GET
Description
Returns all scheduled posts for the current user. Only future posts are returned, ordered by scheduled time (ascending). Supports cursor-based pagination.
The web app does not have a built-in calendar filter for one brand, account, or page. To build a custom filtered calendar, list scheduled posts with this endpoint, then filter the returned items by account.id, account.subaccountId, account.subId, or account.subaccountName.
Query Parameters
limit
integer
No
Number of items per page. Min: 1, Max: 50. Default: 20.
cursor
string
No
Pagination cursor from a previous response.
Response
Status Code: 200 OK
items
array
List of scheduled posts
items[].id
string
Schedule ID. Use this for get, update, and delete operations.
items[].scheduledAt
string
ISO 8601 UTC timestamp for when the post will publish.
items[].account
object or null
The target social account. Null if the account was disconnected.
count
string
Total number of future scheduled posts.
cursor
string
Pagination cursor. Pass this as the cursor query parameter to fetch the next page. Absent when there are no more pages.