> For the complete documentation index, see [llms.txt](https://help.blotato.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.blotato.com/api/mcp/tools.md).

# Tools Reference

The Blotato MCP Server exposes 35 tools. Your AI tool calls these automatically based on your prompts.

## Accounts

### 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 name
* **Output**: 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\_accounts
* **Output**: array of boards with `id` and `name`. Use `id` as `boardId` in 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).

* **Output**: `creditsRemaining`, `accountEmail`, `purchaseQuantityRange` (`min` and `max`), and `pricePer1000CreditsUsd`.

### blotato\_buy\_credits

Create a Stripe Checkout link to buy credits. This does NOT charge anything by itself -- it returns a `checkoutUrl` the account owner opens in a browser to complete payment. Purchased credits land on this account. Confirm the account email with blotato\_get\_credits first, since credits are non-transferable between accounts.

* **Input**: `quantity` (required) - credits to buy, between 1000 and 10000.
* **Output**: `checkoutUrl` - the Stripe Checkout link to open in a browser.

## Publishing

### blotato\_create\_post

Create and publish (or schedule) a post to a social media platform.

* **Input**:
  * `accountId` (required) - from blotato\_list\_accounts
  * `platform` (required) - twitter, instagram, facebook, tiktok, linkedin, pinterest, bluesky, threads, or youtube
  * `text` (required) - post content
  * `mediaUrls` (optional) - array of public media URLs
  * `scheduledTime` (optional) - ISO 8601 datetime
  * `useNextFreeSlot` (optional) - use next available schedule slot
  * `pageId` (optional) - for Facebook/LinkedIn pages
  * `mediaType` (optional) - for Instagram/Facebook: reel or story. Facebook videos must be `"reel"` (regular feed videos no longer supported).
  * `trial` (optional) - for Instagram reels: object with `graduationStrategy` (`"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 TikTok
  * `additionalPosts` (optional) - array of additional posts for threads (Twitter, Bluesky, Threads). Each entry has `text` and `mediaUrls`. The first post uses the top-level `text` and `mediaUrls` fields. Blotato handles reply chaining.
  * `boardId` (optional) - for Pinterest (get from blotato\_list\_pinterest\_boards)
  * `title` (optional) - for Pinterest or YouTube
  * `privacyStatus` (optional) - for YouTube: public, private, or unlisted
  * `playlistIds` (optional) - for YouTube: array of playlist IDs from blotato\_list\_accounts to add the video to playlists
  * `thumbnailUrl` (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 published), errorMessage (when failed)
* **Status values**: in-progress -> published | scheduled | failed

### 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 a `state` field with a `type` of `scheduled`, `published` (includes `postUrl`), or `failed` (includes `errorMessage`).

* **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: 50
  * `cursor` (optional) - pagination cursor from a previous response
  * `status` (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`, and a `state` object. Includes `cursor` for 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) - filter to a single platform: twitter, instagram, facebook, threads, or bluesky. Omit to include all. Analytics for other platforms are not collected yet.
  * `sortBy` (optional) - metric to rank by: `likes_count`, `comments_count`, `views_count`, or `reach_count`. Defaults to `views_count`.
  * `limit` (optional) - number of posts to return. Min: 1, Max: 100. Default: 20
* **Output**: array of `items`, each with `id`, `content`, `postUrl`, `platform`, `createdAt`, `mediaUrls`, `latestMetrics`, and `metricsHistory`.

### 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\_posts
* **Output**: `publishedPostId`, `platform`, `lastFetchedAt`, `lastError`, `metrics` (latest, or null when not synced yet), and `history` (array of snapshots, each with `fetchedAt` and `metrics`).

## 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: 50
  * `cursor` (optional) - pagination cursor from a previous response
  * `platform` (optional) - filter by platform: `instagram` or `facebook`
  * `accountId` (optional) - filter to a single connected account
  * `parentCommentId` (optional) - filter to direct replies to a single comment
  * `postId` (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 timestamp
  * `until` (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`, and `errorMessage` (when failed). Includes `cursor` for the next page when present.

### blotato\_get\_comment

Get a single comment by its Blotato ID.

* **Input**: `commentId` (required) - comment ID from blotato\_list\_comments
* **Output**: `id`, `text`, `status`, `isAuthor`, `platform`, `postId`, `createdAt`, and `errorMessage` (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 plan's 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 8000
  * `parentCommentId` (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: 50
  * `cursor` (optional) - pagination cursor from a previous response
  * `platform` (optional) - filter by platform: `instagram` or `facebook`
  * `accountId` (optional) - filter to a single connected account
* **Output**: array of conversations with `id`, `platform`, `participants`, `updatedAt`, and `createdAt`. Includes `cursor` for the next page when present.

### blotato\_get\_conversation

Get a single conversation by its Blotato ID.

* **Input**: `conversationId` (required) - conversation ID from blotato\_list\_conversations
* **Output**: conversation object with `id`, `platform`, `participants`, and `updatedAt`

### 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: 50
  * `cursor` (optional) - pagination cursor from a previous response
  * `conversationId` (optional) - filter to a single conversation
  * `platform` (optional) - filter by platform: `instagram` or `facebook`
  * `accountId` (optional) - filter to a single connected account
* **Output**: array of messages with `id`, `conversationId`, `direction`, `text`, `payload`, `status`, `senderId`, `recipientId`, and `createdAt`. `direction` is `incoming` for messages you receive and `outgoing` for messages you send. Includes `cursor` for 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\_messages
* **Output**: message object with `id`, `conversationId`, `direction`, `text`, `payload`, `status`, `senderId`, `recipientId`, and `createdAt`

### 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) - `instagram` or `facebook`
  * `pageId` (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's `senderId` (from blotato\_list\_messages)
  * `text` (required) - message body. Instagram messages are limited to 1000 bytes, Facebook to 2000 characters. With `buttons` set, the limit drops to 640 characters
  * `commentId` (optional) - to send a private reply to a comment instead of a direct message, pass the comment's Blotato ID
  * `buttons` (optional) - Facebook and Instagram only. 1 to 3 call-to-action buttons pinned under the message. See [Buttons and Quick Replies](#buttons-and-quick-replies)
  * `quickReplies` (optional) - Facebook and Instagram only. 1 to 13 tappable reply chips. See [Buttons and Quick Replies](#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_url` opens a link, `postback` reports the tap back to you
* `title` - button label, 1 to 20 characters
* `url` - required for `web_url`, starts with `https://`
* `payload` - required for `postback`, 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](https://my.blotato.com/settings) to start receiving postback events. Quick-reply taps need no reconnect.

See [Buttons and Quick Replies](/api/messages.md#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](/features/dm-automations.md).

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 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](/settings/billing-and-credits.md#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\_accounts
  * `platform` (required) - `instagram` or `facebook`
  * `pageId` (required for Facebook) - the Facebook Page from the account's subaccounts
  * `name` (required) - automation label
  * `trigger` (required) - `type` (`comment-received` or `message-received`), `keywords` (omit or empty to match anything), `postId` (comment triggers only, the Blotato post ID to watch, omit for any post), `isActive` (default true)
  * `dmMessage` (required) - the message sent when the trigger fires, 1 to 640 characters
  * `buttons` (optional) - up to 3 link buttons, each with `type: "url"`, a `title` of 20 characters or fewer, and a `url`
  * `followGate` (optional, Instagram only) - `message` (1 to 640 characters) and `buttonTitle` (20 characters or fewer, default `I'm following`). Holds the DM back until the contact follows the account. Rejected on a Facebook automation
  * `emailGate` (optional) - `message` (1 to 640 characters). Holds the DM back until the contact replies with an email address
  * `webhook` (optional) - `method` (`GET`, `POST`, `PUT`, `PATCH`, or `DELETE`), `url` (public `http(s)`, 2048 characters or fewer), and `headers` (optional). Called once the DM sends
  * `isActive` (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 1 hour 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.

Any 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 1 hour, 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 webhook is the only way to read a captured address, since blotato\_list\_conversations and blotato\_list\_messages do not return it.

**Webhook.** Every method except `GET` carries a JSON body: `{"email": "them@example.com"}` with an email gate, `{}` without. `GET` carries no body. The host must resolve to a public address, redirects are not followed, and the timeout is 10 seconds. A non-2xx response gets logged and the run still completes. A blocked address, a DNS failure, or a timeout 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.

* **Input**:
  * `limit` (optional) - number of automations per page. Min: 1, Max: 250. Default: 50
  * `cursor` (optional) - pagination cursor from a previous response
* **Output**: array of automations with `id`, `name`, `platform`, `target`, `trigger`, `dmMessage`, `buttons`, `emailGate`, `followGate`, `webhook`, `isActive`, and `createdAt`. Includes `cursor` for the next page when present.

### blotato\_update\_automation

Update a DM automation. Any of `name`, `trigger`, `dmMessage`, `buttons`, `followGate`, `emailGate`, or `webhook` you pass replaces that field. Omitted fields stay unchanged. Pass `null` to remove a trigger, a gate, or a webhook.

Content changes to a live automation publish immediately. Changes to a draft stay saved until you pass `isActive` true. A live automation needs a trigger, so to clear the trigger pass `isActive` false in the same call.

* **Input**:
  * `automationId` (required) - automation ID from blotato\_list\_automations
  * `name` (optional) - new automation label
  * `trigger` (optional) - replaces the trigger
  * `dmMessage` (optional) - replaces the message text
  * `buttons` (optional) - replaces the link buttons
  * `followGate` (optional, Instagram only) - replaces the follow gate. Pass null to remove it
  * `emailGate` (optional) - replaces the email gate. Pass null to remove it
  * `webhook` (optional) - replaces the webhook. Pass null to remove it
  * `isActive` (optional) - true publishes, false moves to draft. Omit to keep the current state
* **Output**: the updated automation

### blotato\_delete\_automation

Archive a DM automation. Its trigger stops listening and the automation stops firing. Runs already in flight finish.

* **Input**: `automationId` (required) - automation ID from blotato\_list\_automations
* **Output**: 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 the 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\_automations
  * `limit` (optional) - number of runs per page. Min: 1, Max: 250. Default: 50
  * `cursor` (optional) - pagination cursor from a previous response
* **Output**: array of runs with `id`, `contactId`, `platform`, `status`, `error` (when failed), `createdAt`, and `updatedAt`
* **Status values**: running, waiting, completed, expired, superseded, failed. A run expires when the contact never answers a gate inside the 1-hour window. 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\_automations
  * `flowRunId` (optional) - filter to a single run, from blotato\_list\_automation\_runs
  * `limit` (optional) - number of logs per page. Min: 1, Max: 250. Default: 50
  * `cursor` (optional) - pagination cursor from a previous response
* **Output**: array of logs with `id`, `flowRunId`, `nodeId`, `level` (`info`, `warning`, `error`), `message`, `context`, and `createdAt`

### blotato\_get\_automation\_analytics

Get all-time run totals for one automation: how many times it was triggered, and how many of those runs completed or failed. Runs still in flight, and runs ending as expired or superseded, count toward `triggered` but not toward either outcome, so `completed` plus `failed` is sometimes lower than `triggered`.

* **Input**: `automationId` (required) - automation ID from blotato\_list\_automations
* **Output**: `triggered`, `completed`, `failed`

***

## 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-query
  * `url` (optional) - required for URL-based source types
  * `text` (optional) - required for text and perplexity-query source types
  * `customInstructions` (optional) - guide extraction (e.g., "focus on key takeaways", "summarize in 5 bullet points")
* **Output**: id, status, title, content (extracted text), and referenceUrl

### 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\_source
* **Output**: status, title, content (when completed), errorMessage (when failed)
* **Status values**: queued -> processing -> completed | failed

***

## Videos and Images

### blotato\_list\_visual\_templates

List all available visual templates (videos, carousels, quote cards, infographics).

* **Input**: `search` (optional) - filter templates by title or description
* **Output**: array of templates with ID, name, and description

### blotato\_create\_visual

Generate an image, carousel, or video from a template.

* **Input**:
  * `templateId` (required) - from blotato\_list\_visual\_templates
  * `prompt` (optional) - describe what you want in natural language
  * `render` (optional, default: true)
* **Output**: visual ID and status (poll with blotato\_get\_visual\_status)

### blotato\_get\_visual\_status

Check the status of a visual generation request.

* **Input**: `id` (required)
* **Output**: status, mediaUrl (for videos), imageUrls (for images/carousels)
* **Status values**: queueing -> generating-script -> script-ready -> generating-media -> media-ready -> exporting -> done | failed

***

## 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: 20
  * `cursor` (optional) - pagination cursor from a previous response
* **Output**: array of schedules with ID, scheduledAt, account info, and draft content. Includes `count` (total) and `cursor` (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\_schedules
* **Output**: 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, provide the same fields as blotato\_create\_post (accountId, platform, text, mediaUrls, and platform-specific fields). Send the full post object -- partial updates are not supported.

* **Input**:
  * `id` (required) - schedule ID from blotato\_list\_schedules
  * `scheduledTime` (optional) - new ISO 8601 timestamp, must be in the future
  * `post` (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\_schedules
* **Output**: 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) and `publicUrl` (the final public URL to use in blotato\_create\_post)
* **Max file size**: depends on your plan (see [Plan Limits](/settings/billing-and-credits.md#plan-limits))
* **Rate limit**: 120 requests per minute

**How to use:**

1. Call `blotato_create_presigned_upload_url` with your filename
2. PUT the file contents to the returned `presignedUrl` with the correct Content-Type header
3. Use the returned `publicUrl` in blotato\_create\_post's `mediaUrls` field

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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.blotato.com/api/mcp/tools.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
