> ## Documentation Index
> Fetch the complete documentation index at: https://docs.postsyncer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Post

> Update an existing post with new content, scheduling, or settings. Only posts that have not been published yet can be updated.

## Update Post

Updates an existing post with new content, scheduling information, or other settings. Only posts that haven't been published yet can be updated. The post can include text content, media attachments, and platform-specific settings.

### Request

<ParamField body="workspace_id" type="integer" required>
  The ID of the workspace where the post will be created
</ParamField>

<ParamField body="labels" type="string[]">
  Optional array of label IDs to apply to this post
</ParamField>

<ParamField body="content" type="object[]" required>
  Array of content objects (threads). Each object can contain text and media. At least one content item with text or media is required.

  <Expandable title="Content Object">
    <ParamField body="text" type="string">
      The text content for this post
    </ParamField>

    <ParamField body="media" type="string[]">
      Each item is a **string** (image/video URL) or (library id from [Media upload file](/api-reference/media/upload-file) / [Import URL](/api-reference/media/upload-url)). Mix allowed. See [Media overview](/api-reference/media/overview).
    </ParamField>

    <ParamField body="cover_image" type="object">
      Optional cover/thumbnail for video posts. Only the **first** content item's `cover_image` is used when publishing. **Which field you use depends on the target platform** - see [Platform requirements](/api-reference/posts/create#platform-requirements-for-cover-images).

      <Expandable title="Cover Image Object">
        <ParamField body="thumbnail" type="string">
          **Custom cover image upload** - workspace media library **id** (image only) or public **HTTPS URL**. **YouTube, Instagram, and Facebook only.** Not used on TikTok.
        </ParamField>

        <ParamField body="video_cover_timestamp_ms" type="integer">
          **Frame selection from the attached video** - timestamp in **milliseconds**. **TikTok only.**
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="is_first_comment" type="boolean">
      When `true`, this content item is posted as the first comment after the main post publishes (Instagram, Facebook, LinkedIn, YouTube). Only one content item may set this. On other platforms in the same post (e.g. TikTok, Threads), the flag does not schedule a first comment — see [First comments](/api-reference/posts/create#first-comments).
    </ParamField>

    <ParamField body="first_comment_delay" type="integer">
      Minutes to wait after publish before posting the first comment. Defaults to `1` when `is_first_comment` is `true`. Max `10080` (7 days).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="schedule_type" type="string" required>
  Type of scheduling. Must be one of: publish\_now, schedule, draft
</ParamField>

<ParamField body="schedule_for" type="object">
  Optional scheduling object used when `schedule_type` is `schedule`. Provide `{"date": "YYYY-MM-DD", "time": "HH:MM", "timezone": "..."}` to schedule for a specific date/time, or omit/leave empty to auto-schedule to the next available time slot

  <Expandable title="Schedule Object">
    <ParamField body="date" type="string" required>
      The date to schedule the post (YYYY-MM-DD format)
    </ParamField>

    <ParamField body="time" type="string" required>
      The time to schedule the post (HH:MM format in 24-hour)
    </ParamField>

    <ParamField body="timezone" type="string">
      Timezone for the scheduled time (defaults to workspace timezone)
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="repeatable" type="boolean">
  Whether the post should be repeated
</ParamField>

<ParamField body="repeatable_times" type="integer" min="2" max="30">
  Number of times to repeat the post. Required if repeatable is true.
</ParamField>

<ParamField body="repeatable_gap" type="integer" min="1" max="100">
  Time gap between repeats. Required if repeatable is true.
</ParamField>

<ParamField body="repeatable_gap_unit" type="string">
  The unit for the repeatable gap. Must be one of: `minutes`, `hours`, `days`, `weeks`, `months`. Required if repeatable is true. Set `repeatable` to `false` to clear repeat scheduling and `repeatable_accounts`.
</ParamField>

<ParamField body="repeatable_accounts" type="integer[]">
  Optional. Only when `repeatable` is true: account IDs in this workspace. To clear repeat scheduling, send `repeatable: false` (see [Update post](/api-reference/posts/update)).
</ParamField>

<Note>
  **[Auto plug](/api-reference/posts/auto-plug)**, **[comment moderation](/api-reference/posts/comment-moderation)**, and **[contact collection](/api-reference/posts/contact-collection)** use dedicated `PATCH` endpoints.
</Note>

<ParamField body="accounts" type="array">
  Array of account objects to publish to

  <Expandable title="Account Object">
    <ParamField body="id" type="integer" required>
      The ID of the social media account
    </ParamField>

    <ParamField body="settings" type="object">
      Platform-specific settings for this post. Optional except for Pinterest which requires a board\_id. The available settings depend on the platform:

      <Expandable title="Twitter/X Settings">
        <ParamField body="for_super_followers_only" type="boolean">
          Whether to restrict the post to super followers only (default: false)
        </ParamField>

        <ParamField body="reply_settings" type="string">
          Who can reply to the post. Options: 'everyone', 'following', 'mentioned\_users' (default: 'everyone')
        </ParamField>

        <ParamField body="quote_tweet_id" type="string">
          ID of the tweet to quote (optional)
        </ParamField>

        <ParamField body="reply" type="object">
          Reply settings object with 'in\_reply\_to\_tweet\_id' (optional)
        </ParamField>

        <ParamField body="community_id" type="string">
          ID of the community to post to (optional)
        </ParamField>

        <ParamField body="share_with_followers" type="boolean">
          Share community post with followers too.
        </ParamField>

        <ParamField body="text" type="string">
          Custom text content for Twitter (optional)
        </ParamField>

        <ParamField body="poll" type="object">
          Poll settings with 'enabled', 'duration\_minutes', 'reply\_settings', and 'options' (optional)

          <Expandable title="Poll Settings">
            <ParamField body="enabled" type="boolean" />

            <ParamField body="duration_minutes" type="string" />

            <ParamField body="reply_settings" type="string">
              everyone, following, mentionedUsers
            </ParamField>

            <ParamField body="options" type="array">
              Poll options, array of text
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>

      <Expandable title="Instagram Settings">
        <ParamField body="post_type" type="string">
          Type of post. Options: 'REELS', 'STORIES', 'POST' (default: 'REELS') (optional)
        </ParamField>

        <ParamField body="caption" type="string">
          Custom caption for Instagram (optional)
        </ParamField>
      </Expandable>

      <Expandable title="Facebook Settings">
        <ParamField body="post_type" type="string">
          Type of post. Options: 'REELS', 'STORIES', 'POST' (default: 'REELS') (optional)
        </ParamField>

        <ParamField body="title" type="string">
          Custom title for the Facebook post (optional)
        </ParamField>

        <ParamField body="link" type="string">
          URL to attach to the post (optional)
        </ParamField>
      </Expandable>

      <Expandable title="LinkedIn Settings">
        <ParamField body="visibility" type="string">
          Post visibility. Options: 'PUBLIC', 'CONNECTIONS', 'LOGGED\_IN' (default: 'PUBLIC')
        </ParamField>

        <ParamField body="link" type="string">
          URL to attach to the post (optional)
        </ParamField>

        <ParamField body="title" type="string">
          Custom title for the LinkedIn post (optional)
        </ParamField>
      </Expandable>

      <Expandable title="YouTube Settings">
        <ParamField body="video_type" type="string">
          Type of video. Options: 'video', 'short' (default: 'video')
        </ParamField>

        <ParamField body="title" type="string">
          Video title (optional)
        </ParamField>

        <ParamField body="description" type="string">
          Video description (optional)
        </ParamField>

        <ParamField body="privacyStatus" type="string">
          Privacy status. Options: 'public', 'private', 'unlisted' (default: 'public')
        </ParamField>

        <ParamField body="tags" type="array">
          Array of tags for the video (optional)
        </ParamField>

        <ParamField body="embeddable" type="boolean">
          Whether the video can be embedded (default: true)
        </ParamField>

        <ParamField body="selfDeclaredMadeForKids" type="boolean">
          Whether the video is made for kids (default: false)
        </ParamField>

        <ParamField body="notifySubscribers" type="boolean">
          Whether to notify subscribers (default: true)
        </ParamField>

        <ParamField body="category_id" type="string">
          YouTube category ID
        </ParamField>
      </Expandable>

      <Expandable title="TikTok Settings">
        <ParamField body="privacy_level" type="string">
          Privacy level for the video (optional) PUBLIC\_TO\_EVERYONE, MUTUAL\_FOLLOW\_FRIENDS, FOLLOWER\_OF\_CREATOR, SELF\_ONLY
        </ParamField>

        <ParamField body="title" type="string">
          Video title (optional)
        </ParamField>

        <ParamField body="description" type="string">
          Video description (optional)
        </ParamField>

        <ParamField body="disable_comment" type="boolean">
          Whether to disable comments (optional)
        </ParamField>

        <ParamField body="disable_duet" type="boolean">
          Whether to disable duets (optional)
        </ParamField>

        <ParamField body="disable_stitch" type="boolean">
          Whether to disable stitches (optional)
        </ParamField>

        <ParamField body="brand_content_toggle" type="boolean">
          Whether to mark as brand content (optional)
        </ParamField>

        <ParamField body="brand_organic_toggle" type="boolean">
          Whether to mark as organic brand content (optional)
        </ParamField>

        <ParamField body="is_aigc" type="boolean">
          Whether the content is AI-generated (optional)
        </ParamField>

        <ParamField body="auto_add_music" type="boolean">
          Whether to auto-add music (optional)
        </ParamField>

        <ParamField body="post_mode" type="string">
          Enum of (optional):
          DIRECT\_POST: Directly post the content to TikTok account.
          MEDIA\_UPLOAD: Upload content to TikTok to complete the post using TikTok's editing flow. Users will receive an inbox notification.
        </ParamField>
      </Expandable>

      <Expandable title="Pinterest Settings">
        <ParamField body="board_id" type="string" required>
          ID of the board to pin to
        </ParamField>

        <ParamField body="link" type="string">
          URL to attach to the pin (optional)
        </ParamField>

        <ParamField body="title" type="string">
          Pin title (optional)
        </ParamField>

        <ParamField body="description" type="string">
          Pin description (optional)
        </ParamField>

        <ParamField body="note" type="string">
          Pin note/description (optional)
        </ParamField>

        <ParamField body="published" type="boolean">
          Whether to publish the pin immediately (default: true)
        </ParamField>
      </Expandable>

      <Expandable title="Threads Settings">
        <ParamField body="title" type="string">
          Custom title for the Threads post (optional)
        </ParamField>

        <ParamField body="link_attachment" type="string">
          URL to attach to the post (optional)
        </ParamField>
      </Expandable>

      <Expandable title="Telegram Settings">
        <ParamField body="title" type="string">
          Custom title for the Telegram message (optional)
        </ParamField>

        <ParamField body="disable_notification" type="boolean">
          Whether to disable notifications (default: false)
        </ParamField>

        <ParamField body="protect_content" type="boolean">
          Whether to protect the content (default: false)
        </ParamField>
      </Expandable>

      <Expandable title="Bluesky Settings">
        <ParamField body="title" type="string">
          Custom title for the Bluesky post (optional)
        </ParamField>

        <ParamField body="website_card" type="object">
          Website card settings with 'uri', 'title', and 'description' (optional)

          <Expandable title="Bluesky Settings Website Card">
            <ParamField body="uri" type="string" />

            <ParamField body="title" type="string" />

            <ParamField body="description" type="string" />
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<RequestExample>
  ```json theme={null}
  {
      "workspace_id": 12,
      "labels": [
          5
      ],
      "content": [
          {
              "text": "Updated: Post Once. Publish everywhere",
              "media": [
                  "https://postsyncer.com/images/og/banner.png?v2"
              ]
          }
      ],
      "schedule_type": "schedule",
      "schedule_for": {
          "date": "2025-07-05",
          "time": "23:00",
          "timezone": "Africa/Addis_Ababa"
      },
      "accounts": [
          {
              "id": 136,
              "settings": {
                  "for_super_followers_only": false,
                  "reply_settings": "everyone",
                  "quote_tweet_id": null,
                  "reply": {
                      "in_reply_to_tweet_id": null
                  },
                  "community_id": null,
                  "share_with_followers": true,
                  "text": null
              }
          }
      ]
  }
  ```
</RequestExample>

### Response

<ResponseField name="id" type="integer">
  Unique identifier for the updated post
</ResponseField>

<ResponseField name="content" type="array">
  Array of content objects with text, media, optional `cover_image`, and optional first-comment fields (`is_first_comment`, `first_comment_delay`). Platform cover requirements: TikTok - `video_cover_timestamp_ms` only; YouTube, Instagram, Facebook - `thumbnail` only.
</ResponseField>

<ResponseField name="status" type="string">
  Status of the post (draft, scheduled, published, failed)
</ResponseField>

<ResponseField name="posted_on" type="array">
  Array of posted timestamps in workspace timezone
</ResponseField>

<ResponseField name="scheduled_at" type="string">
  Scheduled date and time in workspace timezone
</ResponseField>

<ResponseField name="repeatable" type="boolean">
  Whether the post is set to repeat
</ResponseField>

<ResponseField name="repeatable_times" type="integer">
  Number of times the post will repeat
</ResponseField>

<ResponseField name="repeatable_gap" type="integer">
  Gap between repeats
</ResponseField>

<ResponseField name="repeatable_gap_unit" type="string">
  Unit for the repeat gap (hours, days, weeks, months)
</ResponseField>

<ResponseField name="remaining_posts" type="integer">
  Number of remaining posts in the repeat sequence
</ResponseField>

<ResponseField name="workspace" type="object">
  Information about the post's workspace
</ResponseField>

<ResponseField name="labels" type="array">
  Array of labels attached to the post
</ResponseField>

<ResponseField name="platforms" type="array">
  Array of platform-specific post information
</ResponseField>

<ResponseField name="auto_plug" type="object | null">
  Auto plug configuration when enabled, or `null` when off. Update via [Update post auto plug](/api-reference/posts/auto-plug).
</ResponseField>

<ResponseField name="created_at" type="string">
  Creation timestamp in workspace timezone
</ResponseField>

<ResponseField name="updated_at" type="string">
  Last update timestamp in workspace timezone
</ResponseField>

<ResponseExample>
  ```json theme={null}
  { 
    "id": 749,
    "content": [
        {
            "text": "Updated: Post Once. Publish everywhere",
            "media": [
                {
                    "id": 1672,
                    "name": "banner.png",
                    "url": "https://postsyncer.com/images/og/banner.png?v2",
                    "type": "image/png",
                    "size": 210537
                }
            ]
        }
    ],
    "status": "SCHEDULED",
    "posted_on": [],
    "scheduled_at": "2025-07-05 23:00 PM",
    "repeatable": null,
    "repeatable_times": null,
    "repeatable_gap": null,
    "repeatable_gap_unit": null,
    "remaining_posts": null,
    "created_at": "2025-07-05 17:04 PM",
    "updated_at": "2025-07-05 17:05 PM",
    "workspace": {
        "id": 12,
        "name": "abdulmejidshemsuawel",
        "slug": "abdulmejidshemsuawel",
        "type": "PERSONAL",
        "logo": null,
        "timezone": "Africa/Addis_Ababa",
        "language": "en"
    },
    "labels": [
        {
            "id": 5,
            "name": "ol pasdm",
            "color": "#bf3434"
        }
    ],
    "platforms": [
        {
            "platform": "twitter",
            "posted_on": [],
            "status": "PENDING",
            "settings": {
                "for_super_followers_only": false,
                "reply_settings": "everyone",
                "quote_tweet_id": null,
                "reply": {
                    "in_reply_to_tweet_id": null
                },
                "community_id": null,
                "share_with_followers": true,
                "text": "",
                "poll": {
                    "enabled": false,
                    "duration_minutes": null,
                    "reply_settings": "everyone",
                    "options": null
                }
            }
        }
    ],
    "auto_plug": null 
  }
  ```
</ResponseExample>

### Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT "https://postsyncer.com/api/v1/posts/749" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "workspace_id": 12,
      "labels": [
        5
      ],
      "content": [
        {
          "text": "Updated: Post Once. Publish everywhere",
          "media": [
            "https://postsyncer.com/images/og/banner.png?v2"
          ]
        }
      ],
      "schedule_type": "schedule",
      "schedule_for": {
        "date": "2025-07-05",
        "time": "23:00",
        "timezone": "Africa/Addis_Ababa"
      },
      "accounts": [
        {
          "id": 136,
          "settings": {
            "for_super_followers_only": false,
            "reply_settings": "everyone",
            "quote_tweet_id": null,
            "reply": {
              "in_reply_to_tweet_id": null
            },
            "community_id": null,
            "share_with_followers": true,
            "text": null
          }
        }
      ]
    }'
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');

  const updatePost = async (postId) => {
    try {
      const response = await axios.put(`https://postsyncer.com/api/v1/posts/${postId}`, {
        workspace_id: 12,
        labels: [
          5
        ],
        content: [
          {
            text: 'Updated: Post Once. Publish everywhere',
            media: [
              'https://postsyncer.com/images/og/banner.png?v2'
            ]
          }
        ],
        schedule_type: 'schedule',
        schedule_for: {
          date: '2025-07-05',
          time: '23:00',
          timezone: 'Africa/Addis_Ababa'
        },
        accounts: [
          {
            id: 136,
            settings: {
              for_super_followers_only: false,
              reply_settings: 'everyone',
              quote_tweet_id: null,
              reply: {
                in_reply_to_tweet_id: null
              },
              community_id: null,
              share_with_followers: true,
              text: null
            }
          }
        ]
      }, {
        headers: {
          'Authorization': 'Bearer YOUR_API_TOKEN',
          'Content-Type': 'application/json'
        }
      });
      
      console.log('Post updated:', response.data);
    } catch (error) {
      console.error('Error updating post:', error.response?.data || error.message);
    }
  };

  updatePost(749);
  ```

  ```php PHP theme={null}
  <?php

  $postId = 749;
  $data = [
      'workspace_id' => 12,
      'labels' => [
          5
      ],
      'content' => [
          [
              'text' => 'Updated: Post Once. Publish everywhere',
              'media' => [
                  'https://postsyncer.com/images/og/banner.png?v2'
              ]
          ]
      ],
      'schedule_type' => 'schedule',
      'schedule_for' => [
          'date' => '2025-07-05',
          'time' => '23:00',
          'timezone' => 'Africa/Addis_Ababa'
      ],
      'accounts' => [
          [
              'id' => 136,
              'settings' => [
                  'for_super_followers_only' => false,
                  'reply_settings' => 'everyone',
                  'quote_tweet_id' => null,
                  'reply' => [
                      'in_reply_to_tweet_id' => null
                  ],
                  'community_id' => null,
                  'share_with_followers': true,
                  'text' => null
              ]
          ]
      ]
  ];

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://postsyncer.com/api/v1/posts/{$postId}");
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: Bearer YOUR_API_TOKEN',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($httpCode === 200) {
      $post = json_decode($response, true);
      echo "Post updated: " . $post['data']['id'];
  } else {
      echo "Error: " . $response;
  }
  ?>
  ```

  ```python Python theme={null}
  import requests
  import json

  post_id = 749
  data = {
      'workspace_id': 12,
      'labels': [
          5
      ],
      'content': [
          {
              'text': 'Updated: Post Once. Publish everywhere',
              'media': [
                  'https://postsyncer.com/images/og/banner.png?v2'
              ]
          }
      ],
      'schedule_type': 'schedule',
      'schedule_for': {
          'date': '2025-07-05',
          'time': '23:00',
          'timezone': 'Africa/Addis_Ababa'
      },
      'accounts': [
          {
              'id': 136,
              'settings': {
                  'for_super_followers_only': False,
                  'reply_settings': 'everyone',
                  'quote_tweet_id': None,
                  'reply': {
                      'in_reply_to_tweet_id': None
                  },
                  'community_id': None,
                  'share_with_followers': true,
                  'text': None
              }
          }
      ]
  }

  headers = {
      'Authorization': 'Bearer YOUR_API_TOKEN',
      'Content-Type': 'application/json'
  }

  response = requests.put(
      f'https://postsyncer.com/api/v1/posts/{post_id}',
      json=data,
      headers=headers
  )

  if response.status_code == 200:
      post = response.json()
      print(f"Post updated: {post['data']['id']}")
  else:
      print(f"Error: {response.status_code}")
      print(response.text)
  ```
</CodeGroup>

### Platform-Specific Settings

Each social media platform supports different settings that allow you to customize how your post appears and behaves. These settings are specified in the `settings` object for each account in the `accounts` array.

#### Twitter/X Settings

* **for\_super\_followers\_only**: Restrict post visibility to super followers
* **reply\_settings**: Control who can reply ('everyone', 'following', 'mentioned\_users')
* **quote\_tweet\_id**: Quote an existing tweet
* **reply**: Reply to a specific tweet
* **community\_id**: Post to a specific community
* **share\_with\_followers**: Share community post with followers too
* **text**: Override the main text content for Twitter
* **poll**: Create a poll with options and duration

#### Instagram Settings

* **post\_type**: Choose between 'REELS', 'STORIES', 'POST' (optional)
* **caption**: Custom caption with hashtags and mentions

#### Facebook Settings

* **title**: Custom title for the post
* **link**: Attach a URL to the post

#### LinkedIn Settings

* **visibility**: Control post visibility ('PUBLIC', 'CONNECTIONS', 'LOGGED\_IN')
* **link**: Attach a URL to the post
* **title**: Custom title for the post

#### YouTube Settings

* **video\_type**: Choose between 'video' or 'short'
* **title**: Video title
* **description**: Video description
* **privacyStatus**: Set privacy ('public', 'private', 'unlisted')
* **tags**: Array of tags for better discoverability
* **embeddable**: Allow video embedding
* **selfDeclaredMadeForKids**: Mark as content for children
* **notifySubscribers**: Send notifications to subscribers
* **category\_id**: YouTube category

#### TikTok Settings

* **privacy\_level**: Set video privacy (PUBLIC\_TO\_EVERYONE, MUTUAL\_FOLLOW\_FRIENDS, FOLLOWER\_OF\_CREATOR, SELF\_ONLY)
* **title**: Video title
* **description**: Video description
* **disable\_comment**: Turn off comments
* **disable\_duet**: Disable duet feature
* **disable\_stitch**: Disable stitch feature
* **brand\_content\_toggle**: Mark as brand content
* **brand\_organic\_toggle**: Mark as organic brand content
* **is\_aigc**: Indicate AI-generated content
* **auto\_add\_music**: Automatically add music
* **post\_mode**: Enum: DIRECT\_POST (post directly) | MEDIA\_UPLOAD (upload for user to finish in TikTok)

#### Pinterest Settings

* **board\_id**: Specify which board to pin to
* **link**: Attach a URL to the pin
* **title**: Pin title
* **description**: Pin description
* **note**: Additional pin notes
* **published**: Publish immediately or save as draft

#### Threads Settings

* **title**: Custom title for the post
* **link\_attachment**: Attach a URL to the post

#### Telegram Settings

* **title**: Custom title for the message
* **disable\_notification**: Send silently
* **protect\_content**: Protect from forwarding

#### Bluesky Settings

* **title**: Custom title for the post
* **website\_card**: Add a website card with URI, title, and description

### Media Guidelines

Different social platforms have different requirements for media. PostSyncer will automatically process your media to meet platform requirements, but keep these limitations in mind:

#### Video cover images

Set `content[0].cover_image` when updating a video post. Only the first content thread's cover is applied when publishing.

#### Platform requirements for cover images

| Platform                     | Cover method                        | API field                  |
| ---------------------------- | ----------------------------------- | -------------------------- |
| **TikTok**                   | Frame selection from video **only** | `video_cover_timestamp_ms` |
| **YouTube**                  | Custom thumbnail upload **only**    | `thumbnail`                |
| **Instagram** (Reels)        | Custom thumbnail upload **only**    | `thumbnail`                |
| **Facebook** (Reels / video) | Custom thumbnail upload **only**    | `thumbnail`                |

<Note>
  **TikTok:** use `video_cover_timestamp_ms` only - no custom thumbnail upload. **YouTube, Instagram, Facebook:** use `thumbnail` only - upload a cover image to the media library (or pass a public image URL).
</Note>

| Platform  | Max Images | Max Videos | Required Media | Max File Size             |
| --------- | ---------- | ---------- | -------------- | ------------------------- |
| Twitter/X | 4          | 1          | No             | 5MB (img), 512MB (video)  |
| Facebook  | 10         | 1          | No             | 10MB (img), 4GB (video)   |
| Instagram | 10         | 1          | Yes            | 8MB (img), 100MB (video)  |
| TikTok    | 35         | 1          | Yes            | 20MB (img), 4GB (video)   |
| YouTube   | 0          | 1          | Yes            | N/A, 10GB (video)         |
| Pinterest | 5          | 1          | Yes            | 20MB (img), 200MB (video) |
| Threads   | 10         | 10         | No             | 8MB (img), 1GB (video)    |
| Telegram  | 10         | 10         | No             | 5MB (img), 20MB (video)   |
| LinkedIn  | 9          | 1          | No             | 5MB (img), 512MB (video)  |
| Bluesky   | 4          | 1          | No             | 1MB (img), 100MB (video)  |

### Error Codes

<ResponseField name="400" type="Bad Request">
  Validation errors, invalid parameters, or invalid media URLs
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  Missing or invalid API token
</ResponseField>

<ResponseField name="403" type="Forbidden">
  Token does not have 'posts' permission
</ResponseField>

<ResponseField name="404" type="Not Found">
  Post not found or user does not have access to the post's workspace
</ResponseField>

<ResponseField name="422" type="Unprocessable Entity">
  Validation errors in request data
</ResponseField>
