> 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/rest-api-reference/publish-post.md).

# Post

Build a REST publish request with platform-specific targets, media, scheduling fields, and a submission ID for verification.

## 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](/rest-api-reference/publish-post/get-post.md) with the returned `postSubmissionId` to track publishing progress.

### Before You Start

1. Fetch your connected accounts: `GET /v2/users/me/accounts` ([docs](/rest-api-reference/accounts.md))
2. Fetch your subaccounts to get `pageId` for Facebook/LinkedIn and `playlistIds` for YouTube: `GET /v2/users/me/accounts/{accountId}/subaccounts` ([docs](/rest-api-reference/accounts.md#list-subaccounts-pages)).
3. For a social platform, set `content.platform` and `target.targetType` to the same value (e.g., both `"twitter"`). The webhook target uses `other` and `webhook`.

***

### Request Body

The request body has two top-level fields: `post` (required) and optional scheduling fields. Do not nest scheduling fields inside `post`.

| Field             | Type      | Required | Description                                                                                                                         |
| ----------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `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 `scheduledTime` is set, it supplies the publish time. Setting `useNextFreeSlot: true` as well still runs slot validation and fails when no matching slot is available. Do not combine the fields.
* If `useNextFreeSlot` is `true` (and no `scheduledTime`): the post is scheduled at the next available calendar slot matching the destination.
* If neither `scheduledTime` nor `useNextFreeSlot` is provided: **the post publishes immediately.**
* Both fields must be **root-level** (siblings of `post`). If they are nested inside `post`, `options`, or any other object, they are ignored and the post publishes immediately.

### `post` Object

| Field       | Type     | Required | Description                                                           |
| ----------- | -------- | -------- | --------------------------------------------------------------------- |
| `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

| Field             | Type               | Required | Description                                                                                                                                                                                                  |
| ----------------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `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   | `"twitter"`   | (none)                                                                                                                   | (none)                                                                                                        |
| LinkedIn  | `"linkedin"`  | (none)                                                                                                                   | `pageId`                                                                                                      |
| Facebook  | `"facebook"`  | `pageId`                                                                                                                 | `mediaType`, `link`, `firstComment`                                                                           |
| Instagram | `"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 | `"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)                                                                                                        |

***

#### Twitter

| Field        | Type        | Required |
| ------------ | ----------- | -------- |
| `targetType` | `"twitter"` | Yes      |

#### LinkedIn

| Field        | Type         | Required | Description                                                                                                                            |
| ------------ | ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `targetType` | `"linkedin"` | Yes      |                                                                                                                                        |
| `pageId`     | `string`     | No       | LinkedIn Company Page ID from [subaccounts](/rest-api-reference/accounts.md#list-subaccounts-pages). Omit to post to personal profile. |

**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.

#### Facebook

| Field          | Type                  | Required        | Description                                                                                                                                                                                                                                                                                                                                        |
| -------------- | --------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `targetType`   | `"facebook"`          | Yes             |                                                                                                                                                                                                                                                                                                                                                    |
| `pageId`       | `string`              | Yes             | Facebook Page ID from [subaccounts](/rest-api-reference/accounts.md#list-subaccounts-pages).                                                                                                                                                                                                                                                       |
| `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](/tips-and-tricks/social-platform-requirements.md#facebook). |
| `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.                                                                                                                                                                                                       |

#### Instagram

| Field           | Type                  | Required | Description                                                                                                                                                                                         |
| --------------- | --------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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](/social-accounts-and-platform-faqs/instagram/limitations.md#story-captions-and-text-overlays).

**`trial` Object**

| Field                | Type     | Required | Description                                                                                                          |
| -------------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `graduationStrategy` | `string` | Yes      | `"MANUAL"` (you promote to followers manually) or `"SS_PERFORMANCE"` (Instagram auto-promotes based on performance). |

#### TikTok

| Field                 | Type       | Required | Description                                                                                                                                                     |
| --------------------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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.

#### Pinterest

| Field        | Type          | Required | Description                                                                                                  |
| ------------ | ------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| `targetType` | `"pinterest"` | Yes      |                                                                                                              |
| `boardId`    | `string`      | Yes      | Pinterest Board ID. [Get from List Pinterest Boards](/rest-api-reference/accounts.md#list-pinterest-boards). |
| `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

| Field          | Type        | Required | Description                                            |
| -------------- | ----------- | -------- | ------------------------------------------------------ |
| `targetType`   | `"threads"` | Yes      |                                                        |
| `replyControl` | `string`    | No       | `everyone`, `accounts_you_follow`, or `mentioned_only` |

#### Bluesky

| Field        | Type        | Required |
| ------------ | ----------- | -------- |
| `targetType` | `"bluesky"` | Yes      |

#### YouTube

| Field                     | Type               | Required | Description                                                                                                                          |
| ------------------------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `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.                                                                                         |
| `playlistIds`             | `array of strings` | No       | YouTube playlist IDs to add the video to. Get from [subaccounts](/rest-api-reference/accounts.md#list-subaccounts-pages).            |
| `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](https://support.google.com/youtube/answer/146402?hl=en)).

#### 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.

| Field        | Type        | Required | Description                            |
| ------------ | ----------- | -------- | -------------------------------------- |
| `targetType` | `"webhook"` | Yes      |                                        |
| `url`        | `string`    | Yes      | The webhook URL to send the post data. |

***

### Response

**Status Code:** `201 Created`

```json
{
  "postSubmissionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "scheduledTime": "2025-03-10T15:30:00Z"
}
```

| Field              | Type     | Description                                                                                                                        |
| ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `postSubmissionId` | `string` | ID of the post submission. Use it to poll [Get Post Status](/rest-api-reference/publish-post/get-post.md) 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)

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98432",
    "content": {
      "text": "Hello, world!",
      "mediaUrls": [],
      "platform": "twitter"
    },
    "target": {
      "targetType": "twitter"
    }
  }
}
```

#### 2. Instagram Post with Images

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98434",
    "content": {
      "text": "Check out these photos!",
      "mediaUrls": [
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg"
      ],
      "platform": "instagram"
    },
    "target": {
      "targetType": "instagram",
      "firstComment": "Full guide: https://blotato.com"
    }
  }
}
```

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

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98433",
    "content": {
      "text": "New product announcement!",
      "mediaUrls": ["https://example.com/product.jpg"],
      "platform": "facebook"
    },
    "target": {
      "targetType": "facebook",
      "pageId": "123456789"
    }
  }
}
```

Get `accountId` and `pageId` from the [Accounts endpoints](/rest-api-reference/accounts.md#facebook).

#### 4. TikTok Post (all required fields)

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98435",
    "content": {
      "text": "Tips for productivity",
      "mediaUrls": ["https://example.com/video.mp4"],
      "platform": "tiktok"
    },
    "target": {
      "targetType": "tiktok",
      "privacyLevel": "PUBLIC_TO_EVERYONE",
      "disabledComments": false,
      "disabledDuet": false,
      "disabledStitch": false,
      "isBrandedContent": false,
      "isYourBrand": false,
      "isAiGenerated": true
    }
  }
}
```

#### 5. Scheduled Post

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98432",
    "content": {
      "text": "This will go live later",
      "mediaUrls": [],
      "platform": "twitter"
    },
    "target": {
      "targetType": "twitter"
    }
  },
  "scheduledTime": "2025-12-25T15:00:00Z"
}
```

#### 6. Twitter Thread

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98432",
    "content": {
      "text": "Here is a thread about AI content creation (1/3)",
      "mediaUrls": [],
      "platform": "twitter",
      "additionalPosts": [
        {
          "text": "First, research your topic using reliable sources (2/3)",
          "mediaUrls": []
        },
        {
          "text": "Then, create visuals and publish across platforms (3/3)",
          "mediaUrls": []
        }
      ]
    },
    "target": {
      "targetType": "twitter"
    }
  }
}
```

Threads work for Twitter, Bluesky, and Threads.

#### 7. Schedule at Next Free Slot

```http
POST https://backend.blotato.com/v2/posts HTTP/1.1
Content-Type: application/json
blotato-api-key: YOUR_API_KEY

{
  "post": {
    "accountId": "98432",
    "content": {
      "text": "Scheduled to the next free slot",
      "mediaUrls": [],
      "platform": "twitter"
    },
    "target": {
      "targetType": "twitter"
    }
  },
  "useNextFreeSlot": true
}
```

`useNextFreeSlot` and `scheduledTime` are top-level fields, not inside `post`.


---

# 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 following URL with the `ask` and `goal` query parameters:

```
GET https://help.blotato.com/rest-api-reference/publish-post.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `build a script that syncs our docs to a CMS` lets GitBook tailor the answer to that use case.

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.
