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

# Validate post

> Validates a post without creating one.

This endpoint applies the same validation rules as `POST /posts`,
including social account resolution, platform-specific validation, and
media validation for referenced media library items.




## OpenAPI

````yaml /openapi.yaml post /posts/validate
openapi: 3.1.0
info:
  title: WoopSocial API
  version: 1.0.0
  summary: API for WoopSocial integrations.
  description: >
    This is the public-facing OpenAPI contract for WoopSocial. It supports
    scheduling posts for various social media platforms such as Facebook,
    Instagram, LinkedIn, LinkedIn Pages, Pinterest, Threads, TikTok, X (formerly
    Twitter) and YouTube.
servers:
  - url: https://api.woopsocial.com/v1
    description: WoopSocial API URL.
  - url: http://localhost:9123/api/external/v1
    description: Local WoopSocial API URL.
security: []
tags:
  - name: Posts
    description: Post scheduling endpoints.
  - name: Projects
    description: Project discovery endpoints.
  - name: Social Accounts
    description: Connected social account discovery endpoints.
  - name: Media
    description: Media upload endpoints.
  - name: Webhooks
    description: Webhook endpoint management.
  - name: Health
    description: Basic connectivity endpoints.
paths:
  /posts/validate:
    post:
      tags:
        - Posts
      summary: Validate post
      description: |
        Validates a post without creating one.

        This endpoint applies the same validation rules as `POST /posts`,
        including social account resolution, platform-specific validation, and
        media validation for referenced media library items.
      operationId: validatePost
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePostRequest'
      responses:
        '200':
          description: Validation result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidatePostResponse'
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatePostErrorResponse'
      security:
        - ApiKey: []
components:
  schemas:
    CreatePostRequest:
      type: object
      additionalProperties: false
      required:
        - content
        - schedule
        - socialAccounts
      properties:
        content:
          $ref: '#/components/schemas/PostContentInput'
        schedule:
          $ref: '#/components/schemas/PostSchedule'
        autoDeleteMediaAfterPublish:
          type: boolean
          default: false
          description: |
            When true, all media referenced by this post is automatically
            deleted from the media library after all social account deliveries
            for the post have published successfully.
        socialAccounts:
          type: array
          minItems: 1
          description: |
            Social account targets for this post.

            All referenced social accounts must belong to the same project.
            Duplicate `socialAccountId` values are invalid.
          items:
            $ref: '#/components/schemas/SocialAccountInput'
    ValidatePostResponse:
      type: object
      additionalProperties: false
      required:
        - isValid
        - errors
        - warnings
      properties:
        isValid:
          type: boolean
          description: Whether the request passed validation.
        errors:
          type: array
          description: Blocking validation errors. Empty when the request is valid.
          items:
            $ref: '#/components/schemas/ValidationError'
        warnings:
          type: array
          description: Non-blocking validation warnings. Empty when there are no warnings.
          items:
            $ref: '#/components/schemas/ValidationWarning'
    CreatePostErrorResponse:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          $ref: '#/components/schemas/CreatePostErrorCode'
        message:
          type: string
        validationErrors:
          type: array
          items:
            $ref: '#/components/schemas/ValidationError'
          description: Field-level validation failures. Omitted when not applicable.
        conflictingSocialAccountIds:
          type: array
          minItems: 2
          maxItems: 2
          description: |
            Two social account IDs that belong to different projects.

            Returned when `code` is
            `SOCIAL_ACCOUNTS_MUST_BELONG_TO_SAME_PROJECT`.
          items:
            type: string
    PostContentInput:
      type: array
      minItems: 1
      maxItems: 1
      description: |
        Post content expressed as thread items.

        The array exists for future thread support. Currently exactly one item
        is supported.
      items:
        $ref: '#/components/schemas/PostContentItemInput'
    PostSchedule:
      description: When the post should be published.
      oneOf:
        - $ref: '#/components/schemas/DraftPostSchedule'
        - $ref: '#/components/schemas/PublishNowPostSchedule'
        - $ref: '#/components/schemas/ScheduleForLaterPostSchedule'
      discriminator:
        propertyName: type
        mapping:
          DRAFT:
            $ref: '#/components/schemas/DraftPostSchedule'
          PUBLISH_NOW:
            $ref: '#/components/schemas/PublishNowPostSchedule'
          SCHEDULE_FOR_LATER:
            $ref: '#/components/schemas/ScheduleForLaterPostSchedule'
    SocialAccountInput:
      oneOf:
        - $ref: '#/components/schemas/FacebookInput'
        - $ref: '#/components/schemas/InstagramInput'
        - $ref: '#/components/schemas/LinkedInInput'
        - $ref: '#/components/schemas/LinkedInPagesInput'
        - $ref: '#/components/schemas/PinterestInput'
        - $ref: '#/components/schemas/ThreadsInput'
        - $ref: '#/components/schemas/TikTokInput'
        - $ref: '#/components/schemas/WoopTestInput'
        - $ref: '#/components/schemas/XInput'
        - $ref: '#/components/schemas/YouTubeInput'
      discriminator:
        propertyName: platform
        mapping:
          PINTEREST:
            $ref: '#/components/schemas/PinterestInput'
          INSTAGRAM:
            $ref: '#/components/schemas/InstagramInput'
          FACEBOOK:
            $ref: '#/components/schemas/FacebookInput'
          THREADS:
            $ref: '#/components/schemas/ThreadsInput'
          TIKTOK:
            $ref: '#/components/schemas/TikTokInput'
          YOUTUBE:
            $ref: '#/components/schemas/YouTubeInput'
          X:
            $ref: '#/components/schemas/XInput'
          LINKEDIN:
            $ref: '#/components/schemas/LinkedInInput'
          LINKEDIN_PAGES:
            $ref: '#/components/schemas/LinkedInPagesInput'
          WOOPTEST:
            $ref: '#/components/schemas/WoopTestInput'
    ValidationError:
      type: object
      additionalProperties: false
      required:
        - path
        - message
      properties:
        path:
          type: string
          description: JSON path to the invalid input.
        field:
          $ref: '#/components/schemas/ValidationField'
          description: |
            Machine-readable validation field identifier.
        message:
          type: string
    ValidationWarning:
      type: object
      additionalProperties: false
      required:
        - path
        - message
      properties:
        path:
          type: string
          description: JSON path related to the warning.
        field:
          $ref: '#/components/schemas/ValidationField'
          description: |
            Machine-readable validation field identifier.
        message:
          type: string
    CreatePostErrorCode:
      type: string
      enum:
        - INVALID_SOCIAL_ACCOUNT_ID
        - SOCIAL_ACCOUNT_NOT_CONNECTED
        - SOCIAL_ACCOUNTS_MUST_BELONG_TO_SAME_PROJECT
        - DUPLICATE_SOCIAL_ACCOUNT_ID
        - INVALID_MEDIA_ID
        - INVALID_PLATFORM_SPECIFIC_DATA
        - VALIDATION_FAILED
        - INTERNAL_ERROR
    PostContentItemInput:
      type: object
      additionalProperties: false
      minProperties: 1
      properties:
        text:
          type: string
          description: Text content for this thread item.
        media:
          type: array
          items:
            $ref: '#/components/schemas/PostContentMediaInput'
    DraftPostSchedule:
      title: Draft
      type: object
      additionalProperties: false
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - DRAFT
    PublishNowPostSchedule:
      title: Publish Now
      type: object
      additionalProperties: false
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - PUBLISH_NOW
    ScheduleForLaterPostSchedule:
      title: Schedule For Later
      type: object
      additionalProperties: false
      required:
        - type
        - scheduledFor
      properties:
        type:
          type: string
          enum:
            - SCHEDULE_FOR_LATER
        scheduledFor:
          type: string
          format: date-time
          description: UTC time (ISO 8601) when the post should be published.
    FacebookInput:
      title: Facebook
      allOf:
        - $ref: '#/components/schemas/FacebookPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/FacebookFields'
    InstagramInput:
      title: Instagram
      allOf:
        - $ref: '#/components/schemas/InstagramPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/InstagramFields'
    LinkedInInput:
      title: LinkedIn
      allOf:
        - $ref: '#/components/schemas/LinkedInPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/LinkedInFields'
    LinkedInPagesInput:
      title: LinkedIn Pages
      allOf:
        - $ref: '#/components/schemas/LinkedInPagesPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/LinkedInFields'
    PinterestInput:
      title: Pinterest
      allOf:
        - $ref: '#/components/schemas/PinterestPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/PinterestFields'
    ThreadsInput:
      title: Threads
      allOf:
        - $ref: '#/components/schemas/ThreadsPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
    TikTokInput:
      title: TikTok
      allOf:
        - $ref: '#/components/schemas/TikTokPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/TikTokFields'
    WoopTestInput:
      title: WoopTest
      description: >-
        WoopTest is a sandbox platform for testing and debugging. Posts
        targeting `WOOPTEST` go through the full scheduling pipeline but are
        never published to any real social network.
      allOf:
        - $ref: '#/components/schemas/WoopTestPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/WoopTestFields'
    XInput:
      title: X
      allOf:
        - $ref: '#/components/schemas/XPlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
    YouTubeInput:
      title: YouTube
      allOf:
        - $ref: '#/components/schemas/YouTubePlatform'
        - $ref: '#/components/schemas/SocialAccountInputBase'
        - $ref: '#/components/schemas/YouTubeFields'
    ValidationField:
      type: string
      enum:
        - DESCRIPTION
        - MEDIA
        - LINK
        - PINTEREST_BOARD
        - CONTENT
        - TITLE
        - FIRST_COMMENT
        - TIKTOK_PRIVACY_LEVEL
        - TIKTOK_CONTENT_DISCLOSURE
        - YOUTUBE_PRIVACY
        - YOUTUBE_CATEGORY
        - YOUTUBE_TAGS
        - SCHEDULE
    PostContentMediaInput:
      description: |
        Content media reference.
      oneOf:
        - $ref: '#/components/schemas/MediaLibraryPostContentMediaInput'
      discriminator:
        propertyName: type
        mapping:
          MEDIA_LIBRARY:
            $ref: '#/components/schemas/MediaLibraryPostContentMediaInput'
    FacebookPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - FACEBOOK
    SocialAccountInputBase:
      type: object
      required:
        - socialAccountId
      properties:
        socialAccountId:
          type: string
          description: Connected social account identifier.
        contentOverride:
          $ref: '#/components/schemas/PostContentInput'
    FacebookFields:
      type: object
      required:
        - postType
      properties:
        link:
          type: string
        locationId:
          type: string
          description: Facebook place ID to attach to the post.
        postType:
          $ref: '#/components/schemas/FacebookPostType'
    InstagramPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - INSTAGRAM
    InstagramFields:
      type: object
      required:
        - postType
      properties:
        postType:
          $ref: '#/components/schemas/InstagramPostType'
        cover:
          $ref: '#/components/schemas/PostContentMediaInput'
          description: >
            Optional image media reference to use as the cover image for an
            Instagram Reel.


            This field applies only to `postType=REEL`.
    LinkedInPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - LINKEDIN
    LinkedInFields:
      type: object
      properties:
        link:
          type: string
          description: URL to publish as a LinkedIn link preview card.
    LinkedInPagesPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - LINKEDIN_PAGES
    PinterestPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - PINTEREST
    PinterestFields:
      type: object
      required:
        - pinterestBoardId
      properties:
        pinterestBoardId:
          type: string
          description: Identifier of the board to pin to.
        title:
          type: string
        link:
          type: string
          maxLength: 2048
          description: Destination URL to attach to the Pin.
    ThreadsPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - THREADS
    TikTokPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - TIKTOK
    TikTokFields:
      type: object
      required:
        - postType
        - privacyLevel
        - allowComment
        - allowDuet
        - allowStitch
        - isYourBrand
        - isBrandedContent
        - autoAddMusic
      properties:
        postType:
          $ref: '#/components/schemas/TikTokPostType'
        cover:
          $ref: '#/components/schemas/PostContentMediaInput'
          description: |
            Optional image media reference to use as a custom cover for
            `postType=VIDEO`. WoopSocial stitches the image as a single
            frame at the beginning of the video before sending it to TikTok.
        postMode:
          $ref: '#/components/schemas/TikTokPostMode'
          default: DIRECT_POST
          description: >
            TikTok posting mode.


            Defaults to `DIRECT_POST` when omitted.


            `DIRECT_POST` publishes directly to TikTok.


            `MEDIA_UPLOAD` uploads the media to TikTok so the creator can

            finish and publish it in TikTok. Users will receive an inbox
            notification.


            Fields not used by the selected mode may be ignored by TikTok.
        privacyLevel:
          $ref: '#/components/schemas/TikTokPrivacyLevel'
        allowComment:
          type: boolean
          description: Whether comments should be allowed for this TikTok post.
        allowDuet:
          type: boolean
          description: |
            Whether duets should be allowed for this TikTok post.

            This field applies to `postType=VIDEO`.

            When `postType=PHOTO`, this field is required by the API contract
            but is not used by TikTok.
        allowStitch:
          type: boolean
          description: |
            Whether stitches should be allowed for this TikTok post.

            This field applies to `postType=VIDEO`.

            When `postType=PHOTO`, this field is required by the API contract
            but is not used by TikTok.
        isYourBrand:
          type: boolean
          description: >-
            Whether the post should be disclosed as "Your brand" content on
            TikTok.
        isBrandedContent:
          type: boolean
          description: Whether the post should be disclosed as branded content on TikTok.
        isAiGeneratedContent:
          type: boolean
          default: false
          description: >
            Whether the TikTok post contains AI-generated content. This field
            applies to video posts.
        autoAddMusic:
          type: boolean
          description: |
            Whether TikTok should automatically add music to this post.

            This field applies to `postType=PHOTO`.

            When `postType=VIDEO`, this field is required by the API contract
            but is not used by TikTok.
    WoopTestPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - WOOPTEST
    WoopTestFields:
      type: object
      properties:
        shouldSucceed:
          type: boolean
          default: true
          description: |
            Whether the simulated delivery should succeed or fail.

            Defaults to `true`. Set to `false` to simulate a delivery failure.
    XPlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - X
    YouTubePlatform:
      type: object
      required:
        - platform
      properties:
        platform:
          allOf:
            - $ref: '#/components/schemas/SocialPlatform'
            - type: string
              enum:
                - YOUTUBE
    YouTubeFields:
      type: object
      required:
        - title
        - privacy
      properties:
        title:
          type: string
        privacy:
          $ref: '#/components/schemas/YouTubePrivacy'
        category:
          type: string
        tags:
          type: array
          items:
            type: string
        madeForKids:
          type: boolean
    MediaLibraryPostContentMediaInput:
      title: Media Library Input
      type: object
      additionalProperties: false
      required:
        - type
        - mediaId
      properties:
        type:
          type: string
          enum:
            - MEDIA_LIBRARY
        mediaId:
          type: string
          description: >-
            Media identifier create by calling [`POST
            /media/upload-sessions`](/api-reference/media/start-media-upload-session)
            or [`POST /media`](/api-reference/media/upload-media).
    SocialPlatform:
      type: string
      enum:
        - PINTEREST
        - LINKEDIN
        - LINKEDIN_PAGES
        - INSTAGRAM
        - FACEBOOK
        - THREADS
        - TIKTOK
        - X
        - YOUTUBE
        - WOOPTEST
      description: |
        Identifies which social media platform this data structure targets.
    FacebookPostType:
      type: string
      enum:
        - TEXT_ONLY
        - IMAGE
        - VIDEO
        - REEL
        - STORY
    InstagramPostType:
      type: string
      enum:
        - POST
        - REEL
        - STORY
    TikTokPostType:
      type: string
      enum:
        - VIDEO
        - PHOTO
    TikTokPostMode:
      type: string
      enum:
        - DIRECT_POST
        - MEDIA_UPLOAD
    TikTokPrivacyLevel:
      type: string
      enum:
        - PUBLIC_TO_EVERYONE
        - SELF_ONLY
        - MUTUAL_FOLLOW_FRIENDS
        - FOLLOWER_OF_CREATOR
    YouTubePrivacy:
      type: string
      enum:
        - public
        - private
        - unlisted
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      bearerFormat: API key

````