---
title: "Create Post"
method: POST
path: "/v1/posts"
tags: ["Posts"]
---

# Create Post

`POST /v1/posts`

Creates a post for the given social accounts. Note: links are automatically stripped from the caption before publishing to X/Twitter, because X charges far more for posts that contain a link. This covers full URLs (http://, https://, www.) and bare domains like foo.com or foo.io/path. All other platforms keep their links. To share a link on X, post it in a reply or in the account bio.

## Request body

- CreatePostDto
  - `caption` string, required — Caption text for the post
  - `scheduled_at` string, date-time, nullable — Scheduled date and time for the post. Setting to null or undefined will post instantly.
  - `platform_configurations` PlatformConfigurationsDto
    - `pinterest` PinterestConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `board_ids` string[], nullable — Pinterest board IDs
      - `link` string, nullable — Pinterest post link
      - `video_cover_timestamp_ms` number, nullable — Video cover timestamp in milliseconds
      - `title` string, nullable — Pinterest post title
    - `instagram` InstagramConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `video_cover_timestamp_ms` number, nullable — Video cover timestamp in milliseconds
      - `cover_image` string, nullable — Custom cover image for video posts. Pass a media_id obtained from the /v1/media/create-upload-url endpoint. The uploaded image will be used as the cover image for the Instagram video/reel.
      - `placement` 'story', nullable — Set to "story" to publish as an Instagram Story (media_type=STORIES). Stories require exactly one image or video, do not support captions, carousels, custom cover images, or trial reels. Omit for a normal Reel/feed post.
      - `is_trial_reel` boolean, nullable — Enable trial reel mode. Shows reel to non-followers first. Requires: Professional/Creator account, 1,000+ followers, public profile. Max 5 trial reels per day.
      - `trial_graduation` 'MANUAL' | 'SS_PERFORMANCE', nullable — Trial graduation strategy. "MANUAL" (default) = you decide whether to share with all followers. "SS_PERFORMANCE" = auto-graduate based on performance within 72 hours.
      - `user_tags` string[], nullable — Instagram accounts to tag on the post (people tagging — the tagged accounts appear in their "Tagged" photos and get notified, unlike an @mention in the caption). Pass an array of usernames, e.g. ["partner", "brand"]. A leading "@" is optional. Applies to feed photos, carousels and reels; ignored for stories. Tag positions on photos are placed automatically. Tagged accounts must be public and allow tagging, or Instagram silently drops them. Max 20 per post.
      - `collaborators` string[], nullable — Instagram accounts to invite as collaborators (co-authors). The post appears on their profile too and shares its likes and comments, unlike user_tags which only tags them. Pass an array of usernames, e.g. ["partner"]. A leading "@" is optional. Max 3, and they must be public accounts — private or misspelled handles make the post fail. Applies to feed photos, carousels and reels; ignored for stories. Each collaborator gets an invite: the post publishes immediately and appears on their profile once they accept.
      - `first_comment` string, nullable — Optional comment posted on the media immediately after it publishes (a "first comment"). A good place for a link, hashtags, or extra context without cluttering the caption. Ignored for stories. A failed comment will not fail the post — the post still publishes.
    - `tiktok` TiktokConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `title` string, nullable — Overrides the `title` from the post
      - `video_cover_timestamp_ms` number, nullable — Video cover timestamp in milliseconds
      - `draft` boolean, nullable — If true the post will be saved as a draft, instead of immediately publishing
      - `is_aigc` boolean, nullable — If true the video will be labeled with "Creator labeled as AI-generated" tag in the description.
      - `privacy_status` 'public' | 'private', nullable — Set to "private" to publish visible only to you (TikTok SELF_ONLY). Anything else publishes publicly. Defaults to public.
      - `auto_add_music` boolean, nullable — PHOTO POSTS ONLY — has no effect on video posts. When true (the default) TikTok picks a soundtrack for the photo carousel. Set false to publish silent.
      - `allow_comment` boolean, nullable — Allow viewers to comment. Defaults to true.
      - `allow_duet` boolean, nullable — Allow viewers to Duet the video. Defaults to true. Video posts only.
      - `allow_stitch` boolean, nullable — Allow viewers to Stitch the video. Defaults to true. Video posts only.
      - `disclose_branded_content` boolean, nullable — Discloses the post as paid partnership / branded content (TikTok brand_content_toggle). Defaults to false.
      - `disclose_your_brand` boolean, nullable — Discloses the post as promoting your own brand (TikTok brand_organic_toggle). Defaults to false.
    - `twitter` TwitterConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `first_comment` string, nullable — Optional reply posted to the tweet immediately after it publishes (a "first comment"). Unlike the main tweet — where links are stripped to avoid X's URL surcharge — links ARE allowed here, so this is the place to put a URL/CTA. Trimmed to the character limit (280, or 2200 for premium accounts). A failed reply will not fail the post — the tweet still publishes.
    - `youtube` YoutubeConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `title` string, nullable — Overrides the `title` from the post
      - `contains_synthetic_media` boolean, nullable — If true, discloses that the video contains realistic altered or synthetic (AI-generated) content. YouTube may display an "Altered or synthetic content" label to viewers. Maps to the YouTube Data API `status.containsSyntheticMedia` field.
      - `thumbnail` string, nullable — Media ID of an uploaded image to use as the video thumbnail. Upload the image first via the media endpoints, then pass its ID here. Only applies to regular (long-form, horizontal) videos — YouTube ignores custom thumbnails on Shorts (vertical/short videos). The connected YouTube channel must be verified to set custom thumbnails, and the image should be JPEG/PNG, 1280x720, under 2MB. A thumbnail that fails to apply will not fail the post — the video still publishes.
    - `facebook` FacebookConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `placement` 'story', nullable — Set to "story" to publish as a Facebook Page Story (uses /{page-id}/photo_stories or /{page-id}/video_stories). Stories require exactly one image or video and do not support captions or carousels. Omit for a normal feed post.
      - `first_comment` string, nullable — Optional comment posted on the Facebook post immediately after it publishes (a "first comment"). A good place for a link/CTA without cluttering the main post. Ignored for stories (placement: "story"). A failed comment will not fail the post — the post still publishes.
    - `linkedin` LinkedinConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `document_title` string, nullable — Title for a LinkedIn document post (PDF carousel). Only applies when the media is a PDF (a document-kind media_id from /v1/media/create-upload-url). Defaults to the uploaded file name.
    - `bluesky` BlueskyConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
    - `threads` ThreadsConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `location` 'reels' | 'timeline', nullable — Threads post location
      - `first_comment` string, nullable — Optional reply posted to the thread immediately after it publishes (a "first comment"). A good place for a link or extra context without cluttering the main thread. Max 500 characters. A failed reply will not fail the post — the thread still publishes.
    - `google_business` GoogleBusinessConfiguration
      - `caption` string, nullable — Overrides the `caption` from the post
      - `media` string[], nullable — Overrides the `media` from the post
      - `cta_action_type` 'BOOK' | 'ORDER' | 'SHOP' | 'LEARN_MORE' | 'SIGN_UP' | 'CALL', nullable — Call-to-action button shown on the Google Business post. One of BOOK, ORDER, SHOP, LEARN_MORE, SIGN_UP, CALL. Pair with `cta_url` (except CALL which uses the location's phone number).
      - `cta_url` string, nullable — Destination URL for the CTA button. Required when `cta_action_type` is set (except for CALL).
      - `language_code` string, nullable — BCP-47 language code for the post (e.g. "en-US", "es", "fr-CA"). Defaults to "en-US".
  - `account_configurations` AccountConfigurationParentDto
    - `account_configurations` AccountConfigurationDto[] — List of account configurations to override data for specific accounts
      - `account_id` number, required — Id of the social account you want to override
      - `caption` string — Caption to user for the specified account
      - `media` string[] — Array of Media Ids to use for the specifed account
  - `media` string[], nullable — Array of media IDs associated with the post. Some platforms require media to publish (youtube, tiktok, instagram, pinterest) — see the create-post endpoint description for the per-platform media requirements and accepted types.
  - `media_urls` string[], nullable — Array of publicly accesible media URLs associated with the post, will be ignored if media is provided
  - `social_accounts` number[], required — Array of social account IDs for posting
  - `is_draft` boolean, nullable — If true will create the post but not process it until it is updated with a scheduled date or processed instantly
  - `processing_enabled` boolean, nullable — If true will process video files to ensure they post, If false we will skip all video processing
  - `use_queue` object, nullable — Automatically schedule the post to the next available queue slot. Cannot be used together with scheduled_at. Pass true to use your saved timezone, or { timezone: "America/New_York" } to override.

## Response `200`

Post created successfully.

- PostDto
  - `id` string, required — Unique identifier of the post
  - `caption` string, required — Caption text for the post
  - `status` 'posted' | 'scheduled' | 'processing' | 'failed', required — Current status of the post: scheduled, processing, or posted
  - `scheduled_at` object, nullable, required — Scheduled date and time for the post
  - `platform_configurations` object, nullable, required — Platform-specific configurations for the post
  - `social_accounts` number[], required — Array of social account IDs associated with the post
  - `account_configurations` object, nullable, required — Account-specific configurations for the post
  - `media` object, nullable, required — Array of media URLs associated with the post
  - `created_at` string, required — Timestamp when the post was created
  - `updated_at` string, required — Timestamp when the post was last updated
  - `is_draft` boolean, required — If true the post will not be processed until updated
  - `warnings` string[] — Warnings about draft behavior — e.g. platforms that will publish immediately when the draft is sent

## Other responses

- `400` — Invalid request.
- `500` — Internal server error when fetching the Post.

---

[API](https://skmtc.dev/post-bridge/apis/post-bridge-api.md) · [All operations](https://skmtc.dev/post-bridge/apis/post-bridge-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/post-bridge/post-bridge-api/revisions/97ae826701f6/schema)
