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

# Create Post

> Create one or more Posts. Set `when` to publish now, schedule, or save drafts. X, Bluesky, Mastodon, and Threads publish later body items as replies. Use `media_items` to attach Assets to a body item. A Bluesky body item accepts up to four images or one MP4 video. Bluesky images require alt text. A Facebook Post with a video uses the Reel placement automatically. Immediate publication returns before provider work completes. Active provider work returns `202` and `Retry-After`. Read the Post while `terminal` and `action_required` are both false. Do not send Create Post again. Publishing requires `confirmed: true` and a live credential. X Post bodies cannot contain URLs.



## OpenAPI

````yaml https://api.openpmm.com/v1/openapi.json post /workspaces/{workspace_id}/posts
openapi: 3.1.0
info:
  title: OpenPMM API
  version: 1.0.0
  description: >-
    Use one API to create and manage social posts. The signup operation does not
    need an API key. Other operations use an account API key. Workspace
    endpoints also use a workspace ID. Publishing requires explicit
    confirmation.
servers:
  - url: https://api.openpmm.com/v1
    description: Production API
security:
  - bearerAuth: []
tags:
  - name: Signup
    description: Create access to OpenPMM and the first workspace.
  - name: CLI Authorization
    description: Authorize the OpenPMM CLI through a browser sign-in.
  - name: Posts
    description: Create and manage posts.
  - name: Analytics
    description: Read and refresh current post analytics.
  - name: Assets
    description: Upload and manage media files.
  - name: Destinations
    description: Connect and manage social accounts.
  - name: Account
    description: Get account details and list available workspaces.
  - name: Billing
    description: Manage the account subscription and payment details.
  - name: Workspaces
    description: Create and manage workspaces.
  - name: Feedback
    description: Send product feedback to OpenPMM.
  - name: Team
    description: Manage account members and invitations.
  - name: Slack Notifications
    description: Configure Slack notifications.
  - name: Webhooks
    description: Configure signed post status events.
paths:
  /workspaces/{workspace_id}/posts:
    post:
      tags:
        - Posts
      summary: Create Post
      description: >-
        Create one or more Posts. Set `when` to publish now, schedule, or save
        drafts. X, Bluesky, Mastodon, and Threads publish later body items as
        replies. Use `media_items` to attach Assets to a body item. A Bluesky
        body item accepts up to four images or one MP4 video. Bluesky images
        require alt text. A Facebook Post with a video uses the Reel placement
        automatically. Immediate publication returns before provider work
        completes. Active provider work returns `202` and `Retry-After`. Read
        the Post while `terminal` and `action_required` are both false. Do not
        send Create Post again. Publishing requires `confirmed: true` and a live
        credential. X Post bodies cannot contain URLs.
      operationId: createPosts
      parameters:
        - name: workspace_id
          in: path
          required: true
          description: Unique workspace ID.
          schema:
            type: string
            example: ws_01JABCDEF
        - $ref: '#/components/parameters/OpenPMMRequestId'
        - $ref: '#/components/parameters/OptionalIdempotencyKey'
      requestBody:
        $ref: '#/components/requestBodies/CreatePosts'
      responses:
        '200':
          description: An idempotent replay of the existing Post set.
          headers:
            OpenPMM-Request-Id:
              $ref: '#/components/headers/OpenPMMRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostSet'
        '201':
          description: The created draft or post set.
          headers:
            OpenPMM-Request-Id:
              $ref: '#/components/headers/OpenPMMRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostSet'
        '202':
          description: The accepted immediate Post set. Provider work continues.
          headers:
            OpenPMM-Request-Id:
              $ref: '#/components/headers/OpenPMMRequestId'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostSet'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '422':
          $ref: '#/components/responses/UnprocessableContent'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '502':
          $ref: '#/components/responses/BadGateway'
components:
  parameters:
    OpenPMMRequestId:
      name: OpenPMM-Request-Id
      in: header
      required: false
      description: >-
        Optional request ID. OpenPMM returns this value when it is valid.
        Otherwise, OpenPMM creates a request ID.
      schema:
        type: string
        maxLength: 128
      example: req_01JABCDEF
    OptionalIdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Required when you publish or schedule a post. Optional when you create a
        draft.
      schema:
        type: string
        minLength: 1
        maxLength: 200
      example: 01J4Z3Y6K2M8V7C1N5Q9R0T4XA
  requestBodies:
    CreatePosts:
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CreatePostsRequest'
          examples:
            publish_now:
              summary: Publish to X and LinkedIn
              value:
                confirmed: true
                when: now
                group: launch-2026-08
                posts:
                  - destination_id: dest_x_01JABCDEF
                    body:
                      - First post in the thread
                      - Second post
                    media:
                      - ast_01JABCDEF
                  - destination_id: dest_linkedin_01JABCDEF
                    body:
                      - The LinkedIn version, written differently.
                    media:
                      - ast_01JABCDEF
                    destination_options:
                      linkedin:
                        visibility: public
                        allow_resharing: true
            draft:
              summary: Create Drafts
              value:
                when: draft
                group: launch-2026-08
                posts:
                  - channel: x
                    body:
                      - Draft thread
  headers:
    OpenPMMRequestId:
      description: Stable identifier for this request.
      schema:
        type: string
    RetryAfter:
      description: Number of seconds to wait before you retry the request.
      schema:
        type: integer
        minimum: 1
    WWWAuthenticate:
      description: Bearer authentication challenge.
      schema:
        type: string
      example: Bearer realm="openpmm"
  schemas:
    PostSet:
      type: object
      additionalProperties: false
      properties:
        object:
          type: string
          const: post_set
        group:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: ^[A-Za-z0-9_-]+$
              example: launch-2026-08
              description: A value that groups related posts.
            - type: 'null'
        posts:
          type: array
          items:
            $ref: '#/components/schemas/Post'
      required:
        - object
        - group
        - posts
    CreatePostsRequest:
      type: object
      additionalProperties: false
      properties:
        confirmed:
          type: boolean
          const: true
          description: >-
            Set to `true` when you publish or schedule. Omit this field when you
            create a draft.
        when:
          oneOf:
            - type: string
              enum:
                - now
                - draft
                - queue
            - type: string
              format: date-time
          default: now
          description: >-
            Use `now` to publish, `draft` to save a draft, `queue` to use the
            next posting window, or an ISO 8601 timestamp to schedule. A
            timestamp must include a UTC offset.
        time_zone:
          type: string
          default: UTC
          example: Europe/Berlin
          description: >-
            IANA time zone for `now` or an exact schedule. Omit this field for
            `queue`; OpenPMM uses the Workspace time zone.
        group:
          type: string
          minLength: 1
          maxLength: 200
          pattern: ^[A-Za-z0-9_-]+$
          example: launch-2026-08
          description: A value that groups related posts.
        posts:
          type: array
          items:
            oneOf:
              - type: object
                additionalProperties: false
                properties:
                  channel:
                    type: string
                    enum:
                      - bluesky
                      - facebook
                      - instagram
                      - threads
                      - mastodon
                      - x
                      - linkedin
                      - tiktok
                      - youtube
                    example: x
                    description: Channel for this draft Post.
                  headline:
                    anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 10000
                      - type: 'null'
                  body:
                    type: array
                    items:
                      type: string
                      maxLength: 63206
                    minItems: 1
                    maxItems: 25
                    description: >-
                      Ordered post bodies. X, Bluesky, Mastodon, and Threads
                      publish later body items as replies. On those channels, a
                      body item can be empty when media_items attaches media to
                      that item. X post bodies cannot contain URLs.
                  media:
                    type: array
                    items:
                      type: string
                      example: ast_01JABCDEF
                      description: Unique asset ID.
                    maxItems: 100
                    default: []
                    description: >-
                      Assets for the opening post. Use media_items to attach
                      assets to other thread items.
                  media_items:
                    type: array
                    items:
                      type: object
                      additionalProperties: false
                      properties:
                        asset_id:
                          type: string
                          example: ast_01JABCDEF
                          description: Unique asset ID.
                        item_index:
                          type: integer
                          minimum: 0
                          maximum: 24
                          description: The zero-based body item that owns this asset.
                      required:
                        - asset_id
                        - item_index
                    maxItems: 100
                    description: >-
                      Assets and their thread items. Do not use this field with
                      media.
                  destination_options:
                    anyOf:
                      - oneOf:
                          - type: object
                            additionalProperties: false
                            properties:
                              bluesky:
                                type: object
                                additionalProperties: false
                                properties:
                                  languages:
                                    type: array
                                    items:
                                      type: string
                                      minLength: 2
                                      maxLength: 35
                                    maxItems: 3
                                    uniqueItems: true
                                  content_labels:
                                    type: array
                                    items:
                                      type: string
                                      enum:
                                        - porn
                                        - sexual
                                        - nudity
                                        - graphic-media
                                    maxItems: 4
                                    uniqueItems: true
                                  alt_text_by_asset_id:
                                    type: object
                                    description: >-
                                      Map attached asset IDs to alt text.
                                      Bluesky images require alt text. Video alt
                                      text is optional.
                                    additionalProperties:
                                      type: string
                                      minLength: 1
                                      maxLength: 2000
                                    maxProperties: 4
                                required:
                                  - languages
                                  - content_labels
                                  - alt_text_by_asset_id
                            required:
                              - bluesky
                          - type: object
                            additionalProperties: false
                            properties:
                              youtube:
                                type: object
                                additionalProperties: false
                                properties:
                                  kind:
                                    type: string
                                    enum:
                                      - short
                                      - video
                                  privacy_status:
                                    type: string
                                    enum:
                                      - public
                                      - private
                                      - unlisted
                                  category_id:
                                    type: string
                                    minLength: 1
                                    maxLength: 10
                                    example: '22'
                                  license:
                                    type: string
                                    enum:
                                      - youtube
                                      - creative_common
                                    default: youtube
                                  self_declared_made_for_kids:
                                    type: boolean
                                  embeddable:
                                    type: boolean
                                    default: true
                                  contains_synthetic_media:
                                    type: boolean
                                  notify_subscribers:
                                    type: boolean
                                required:
                                  - kind
                                  - privacy_status
                                  - category_id
                                  - self_declared_made_for_kids
                                  - contains_synthetic_media
                                  - notify_subscribers
                            required:
                              - youtube
                          - type: object
                            additionalProperties: false
                            properties:
                              instagram:
                                type: object
                                additionalProperties: false
                                properties:
                                  placement:
                                    type: string
                                    enum:
                                      - post
                                      - story
                                      - reel
                                  share_to_feed:
                                    type: boolean
                                    default: true
                                required:
                                  - placement
                            required:
                              - instagram
                          - type: object
                            additionalProperties: false
                            properties:
                              threads:
                                type: object
                                additionalProperties: false
                                properties:
                                  reply_control:
                                    type: string
                                    enum:
                                      - everyone
                                      - accounts_you_follow
                                      - mentioned_only
                                required:
                                  - reply_control
                            required:
                              - threads
                          - type: object
                            additionalProperties: false
                            properties:
                              mastodon:
                                type: object
                                additionalProperties: false
                                properties:
                                  visibility:
                                    type: string
                                    enum:
                                      - public
                                      - unlisted
                                      - private
                                  sensitive:
                                    type: boolean
                                  spoiler_text:
                                    type: string
                                    maxLength: 500
                                  language:
                                    anyOf:
                                      - type: string
                                        minLength: 2
                                        maxLength: 20
                                      - type: 'null'
                                required:
                                  - visibility
                                  - sensitive
                                  - spoiler_text
                                  - language
                            required:
                              - mastodon
                          - type: object
                            additionalProperties: false
                            properties:
                              linkedin:
                                type: object
                                additionalProperties: false
                                properties:
                                  visibility:
                                    type: string
                                    enum:
                                      - public
                                      - connections
                                  allow_resharing:
                                    type: boolean
                                required:
                                  - visibility
                                  - allow_resharing
                            required:
                              - linkedin
                          - type: object
                            additionalProperties: false
                            properties:
                              tiktok:
                                type: object
                                additionalProperties: false
                                properties:
                                  privacy_level:
                                    type: string
                                    enum:
                                      - public_to_everyone
                                      - mutual_follow_friends
                                      - follower_of_creator
                                      - self_only
                                  allow_comment:
                                    type: boolean
                                  allow_duet:
                                    type: boolean
                                  allow_stitch:
                                    type: boolean
                                  commercial_content:
                                    type: string
                                    enum:
                                      - none
                                      - own_brand
                                      - branded
                                      - both
                                  is_ai_generated:
                                    type: boolean
                                  video_cover_timestamp_ms:
                                    anyOf:
                                      - type: integer
                                        minimum: 0
                                      - type: 'null'
                                required:
                                  - privacy_level
                                  - allow_comment
                                  - allow_duet
                                  - allow_stitch
                                  - commercial_content
                                  - is_ai_generated
                                  - video_cover_timestamp_ms
                            required:
                              - tiktok
                      - type: 'null'
                required:
                  - channel
                  - body
              - type: object
                additionalProperties: false
                properties:
                  destination_id:
                    type: string
                    example: dest_01JABCDEF
                    description: Destination for this Post.
                  headline:
                    anyOf:
                      - type: string
                        minLength: 1
                        maxLength: 10000
                      - type: 'null'
                  body:
                    type: array
                    items:
                      type: string
                      maxLength: 63206
                    minItems: 1
                    maxItems: 25
                    description: >-
                      Ordered post bodies. X, Bluesky, Mastodon, and Threads
                      publish later body items as replies. On those channels, a
                      body item can be empty when media_items attaches media to
                      that item. X post bodies cannot contain URLs.
                  media:
                    type: array
                    items:
                      type: string
                      example: ast_01JABCDEF
                      description: Unique asset ID.
                    maxItems: 100
                    default: []
                    description: >-
                      Assets for the opening post. Use media_items to attach
                      assets to other thread items.
                  media_items:
                    type: array
                    items:
                      type: object
                      additionalProperties: false
                      properties:
                        asset_id:
                          type: string
                          example: ast_01JABCDEF
                          description: Unique asset ID.
                        item_index:
                          type: integer
                          minimum: 0
                          maximum: 24
                          description: The zero-based body item that owns this asset.
                      required:
                        - asset_id
                        - item_index
                    maxItems: 100
                    description: >-
                      Assets and their thread items. Do not use this field with
                      media.
                  destination_options:
                    anyOf:
                      - oneOf:
                          - type: object
                            additionalProperties: false
                            properties:
                              bluesky:
                                type: object
                                additionalProperties: false
                                properties:
                                  languages:
                                    type: array
                                    items:
                                      type: string
                                      minLength: 2
                                      maxLength: 35
                                    maxItems: 3
                                    uniqueItems: true
                                  content_labels:
                                    type: array
                                    items:
                                      type: string
                                      enum:
                                        - porn
                                        - sexual
                                        - nudity
                                        - graphic-media
                                    maxItems: 4
                                    uniqueItems: true
                                  alt_text_by_asset_id:
                                    type: object
                                    description: >-
                                      Map attached asset IDs to alt text.
                                      Bluesky images require alt text. Video alt
                                      text is optional.
                                    additionalProperties:
                                      type: string
                                      minLength: 1
                                      maxLength: 2000
                                    maxProperties: 4
                                required:
                                  - languages
                                  - content_labels
                                  - alt_text_by_asset_id
                            required:
                              - bluesky
                          - type: object
                            additionalProperties: false
                            properties:
                              youtube:
                                type: object
                                additionalProperties: false
                                properties:
                                  kind:
                                    type: string
                                    enum:
                                      - short
                                      - video
                                  privacy_status:
                                    type: string
                                    enum:
                                      - public
                                      - private
                                      - unlisted
                                  category_id:
                                    type: string
                                    minLength: 1
                                    maxLength: 10
                                    example: '22'
                                  license:
                                    type: string
                                    enum:
                                      - youtube
                                      - creative_common
                                    default: youtube
                                  self_declared_made_for_kids:
                                    type: boolean
                                  embeddable:
                                    type: boolean
                                    default: true
                                  contains_synthetic_media:
                                    type: boolean
                                  notify_subscribers:
                                    type: boolean
                                required:
                                  - kind
                                  - privacy_status
                                  - category_id
                                  - self_declared_made_for_kids
                                  - contains_synthetic_media
                                  - notify_subscribers
                            required:
                              - youtube
                          - type: object
                            additionalProperties: false
                            properties:
                              instagram:
                                type: object
                                additionalProperties: false
                                properties:
                                  placement:
                                    type: string
                                    enum:
                                      - post
                                      - story
                                      - reel
                                  share_to_feed:
                                    type: boolean
                                    default: true
                                required:
                                  - placement
                            required:
                              - instagram
                          - type: object
                            additionalProperties: false
                            properties:
                              threads:
                                type: object
                                additionalProperties: false
                                properties:
                                  reply_control:
                                    type: string
                                    enum:
                                      - everyone
                                      - accounts_you_follow
                                      - mentioned_only
                                required:
                                  - reply_control
                            required:
                              - threads
                          - type: object
                            additionalProperties: false
                            properties:
                              mastodon:
                                type: object
                                additionalProperties: false
                                properties:
                                  visibility:
                                    type: string
                                    enum:
                                      - public
                                      - unlisted
                                      - private
                                  sensitive:
                                    type: boolean
                                  spoiler_text:
                                    type: string
                                    maxLength: 500
                                  language:
                                    anyOf:
                                      - type: string
                                        minLength: 2
                                        maxLength: 20
                                      - type: 'null'
                                required:
                                  - visibility
                                  - sensitive
                                  - spoiler_text
                                  - language
                            required:
                              - mastodon
                          - type: object
                            additionalProperties: false
                            properties:
                              linkedin:
                                type: object
                                additionalProperties: false
                                properties:
                                  visibility:
                                    type: string
                                    enum:
                                      - public
                                      - connections
                                  allow_resharing:
                                    type: boolean
                                required:
                                  - visibility
                                  - allow_resharing
                            required:
                              - linkedin
                          - type: object
                            additionalProperties: false
                            properties:
                              tiktok:
                                type: object
                                additionalProperties: false
                                properties:
                                  privacy_level:
                                    type: string
                                    enum:
                                      - public_to_everyone
                                      - mutual_follow_friends
                                      - follower_of_creator
                                      - self_only
                                  allow_comment:
                                    type: boolean
                                  allow_duet:
                                    type: boolean
                                  allow_stitch:
                                    type: boolean
                                  commercial_content:
                                    type: string
                                    enum:
                                      - none
                                      - own_brand
                                      - branded
                                      - both
                                  is_ai_generated:
                                    type: boolean
                                  video_cover_timestamp_ms:
                                    anyOf:
                                      - type: integer
                                        minimum: 0
                                      - type: 'null'
                                required:
                                  - privacy_level
                                  - allow_comment
                                  - allow_duet
                                  - allow_stitch
                                  - commercial_content
                                  - is_ai_generated
                                  - video_cover_timestamp_ms
                            required:
                              - tiktok
                      - type: 'null'
                required:
                  - destination_id
                  - body
          minItems: 1
          maxItems: 100
      required:
        - posts
    Post:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          example: send_01JABCDEF
          description: Unique Post ID.
        object:
          type: string
          const: post
        group:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: ^[A-Za-z0-9_-]+$
              example: launch-2026-08
              description: A value that groups related posts.
            - type: 'null'
        channel:
          type: string
          enum:
            - bluesky
            - facebook
            - instagram
            - threads
            - mastodon
            - x
            - linkedin
            - tiktok
            - youtube
          example: x
        state:
          type: string
          enum:
            - draft
            - preparing
            - scheduled
            - ready
            - processing
            - awaiting-provider
            - published
            - failed
            - needs-attention
            - cancelled
            - missed
        editable:
          type: boolean
          description: >-
            Whether you can update the Post content. A scheduled Post keeps its
            assets and thread structure locked.
        terminal:
          type: boolean
          description: >-
            True when the Post can no longer change state. Poll only while this
            value and `action_required` are false.
        action_required:
          type: boolean
          description: Whether a person or agent must choose the next action.
        next_action_at:
          anyOf:
            - type: string
              format: date-time
              example: '2026-08-09T12:00:00.000Z'
            - type: 'null'
        retry_safety:
          type: string
          enum:
            - safe
            - may_duplicate
            - not_applicable
        available_actions:
          type: array
          items:
            type: string
            enum:
              - update
              - delete
              - publish
              - cancel
              - reschedule
              - retry
              - retry_with_duplicate_risk
        version:
          anyOf:
            - type: integer
              minimum: 1
            - type: 'null'
        payload:
          type: object
          additionalProperties: false
          properties:
            headline:
              anyOf:
                - type: string
                  minLength: 1
                  maxLength: 10000
                - type: 'null'
            body:
              type: array
              items:
                type: string
                maxLength: 63206
              minItems: 1
              maxItems: 25
            destination_options:
              anyOf:
                - oneOf:
                    - type: object
                      additionalProperties: false
                      properties:
                        bluesky:
                          type: object
                          additionalProperties: false
                          properties:
                            languages:
                              type: array
                              items:
                                type: string
                                minLength: 2
                                maxLength: 35
                              maxItems: 3
                              uniqueItems: true
                            content_labels:
                              type: array
                              items:
                                type: string
                                enum:
                                  - porn
                                  - sexual
                                  - nudity
                                  - graphic-media
                              maxItems: 4
                              uniqueItems: true
                            alt_text_by_asset_id:
                              type: object
                              description: >-
                                Map attached asset IDs to alt text. Bluesky
                                images require alt text. Video alt text is
                                optional.
                              additionalProperties:
                                type: string
                                minLength: 1
                                maxLength: 2000
                              maxProperties: 4
                          required:
                            - languages
                            - content_labels
                            - alt_text_by_asset_id
                      required:
                        - bluesky
                    - type: object
                      additionalProperties: false
                      properties:
                        youtube:
                          type: object
                          additionalProperties: false
                          properties:
                            kind:
                              type: string
                              enum:
                                - short
                                - video
                            privacy_status:
                              type: string
                              enum:
                                - public
                                - private
                                - unlisted
                            category_id:
                              type: string
                              minLength: 1
                              maxLength: 10
                              example: '22'
                            license:
                              type: string
                              enum:
                                - youtube
                                - creative_common
                              default: youtube
                            self_declared_made_for_kids:
                              type: boolean
                            embeddable:
                              type: boolean
                              default: true
                            contains_synthetic_media:
                              type: boolean
                            notify_subscribers:
                              type: boolean
                          required:
                            - kind
                            - privacy_status
                            - category_id
                            - self_declared_made_for_kids
                            - contains_synthetic_media
                            - notify_subscribers
                      required:
                        - youtube
                    - type: object
                      additionalProperties: false
                      properties:
                        instagram:
                          type: object
                          additionalProperties: false
                          properties:
                            placement:
                              type: string
                              enum:
                                - post
                                - story
                                - reel
                            share_to_feed:
                              type: boolean
                              default: true
                          required:
                            - placement
                      required:
                        - instagram
                    - type: object
                      additionalProperties: false
                      properties:
                        threads:
                          type: object
                          additionalProperties: false
                          properties:
                            reply_control:
                              type: string
                              enum:
                                - everyone
                                - accounts_you_follow
                                - mentioned_only
                          required:
                            - reply_control
                      required:
                        - threads
                    - type: object
                      additionalProperties: false
                      properties:
                        mastodon:
                          type: object
                          additionalProperties: false
                          properties:
                            visibility:
                              type: string
                              enum:
                                - public
                                - unlisted
                                - private
                            sensitive:
                              type: boolean
                            spoiler_text:
                              type: string
                              maxLength: 500
                            language:
                              anyOf:
                                - type: string
                                  minLength: 2
                                  maxLength: 20
                                - type: 'null'
                          required:
                            - visibility
                            - sensitive
                            - spoiler_text
                            - language
                      required:
                        - mastodon
                    - type: object
                      additionalProperties: false
                      properties:
                        linkedin:
                          type: object
                          additionalProperties: false
                          properties:
                            visibility:
                              type: string
                              enum:
                                - public
                                - connections
                            allow_resharing:
                              type: boolean
                          required:
                            - visibility
                            - allow_resharing
                      required:
                        - linkedin
                    - type: object
                      additionalProperties: false
                      properties:
                        tiktok:
                          type: object
                          additionalProperties: false
                          properties:
                            privacy_level:
                              type: string
                              enum:
                                - public_to_everyone
                                - mutual_follow_friends
                                - follower_of_creator
                                - self_only
                            allow_comment:
                              type: boolean
                            allow_duet:
                              type: boolean
                            allow_stitch:
                              type: boolean
                            commercial_content:
                              type: string
                              enum:
                                - none
                                - own_brand
                                - branded
                                - both
                            is_ai_generated:
                              type: boolean
                            video_cover_timestamp_ms:
                              anyOf:
                                - type: integer
                                  minimum: 0
                                - type: 'null'
                          required:
                            - privacy_level
                            - allow_comment
                            - allow_duet
                            - allow_stitch
                            - commercial_content
                            - is_ai_generated
                            - video_cover_timestamp_ms
                      required:
                        - tiktok
                - type: 'null'
          required:
            - headline
            - body
            - destination_options
        asset_ids:
          type: array
          items:
            type: string
            example: ast_01JABCDEF
            description: Unique asset ID.
          maxItems: 100
        destination_id:
          anyOf:
            - type: string
              example: dest_01JABCDEF
              description: Unique destination ID.
            - type: 'null'
        scheduled_at:
          anyOf:
            - type: string
              format: date-time
              example: '2026-08-09T12:00:00.000Z'
            - type: 'null'
        time_zone:
          anyOf:
            - type: string
              example: Europe/Berlin
            - type: 'null'
        schedule_mode:
          anyOf:
            - type: string
              enum:
                - now
                - exact
                - queue
            - type: 'null'
        queue_local_date:
          anyOf:
            - type: string
              format: date
            - type: 'null'
        queue_window_id:
          anyOf:
            - type: string
            - type: 'null'
        attempt_count:
          type: integer
          minimum: 0
        deferred:
          anyOf:
            - type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  enum:
                    - publishing_velocity
                    - provider_cooldown
                until:
                  type: string
                  format: date-time
                  example: '2026-08-09T12:00:00.000Z'
              required:
                - reason
                - until
              description: >-
                The future time when OpenPMM can try the Post again. This value
                is null after that time.
            - type: 'null'
        last_error:
          anyOf:
            - type: object
              additionalProperties: false
              properties:
                code:
                  type: string
                  example: provider_rejected
                message:
                  type: string
                  example: The provider rejected the post.
                retryable:
                  type: boolean
                retry_safety:
                  type: string
                  enum:
                    - safe
                    - may_duplicate
                    - not_applicable
                user_action:
                  type: string
                  enum:
                    - retry
                    - verify_provider
                    - reauthorize
                    - check_request
              required:
                - code
                - message
                - retryable
                - retry_safety
                - user_action
            - type: 'null'
        created_at:
          type: string
          format: date-time
          example: '2026-08-09T12:00:00.000Z'
        updated_at:
          type: string
          format: date-time
          example: '2026-08-09T12:00:00.000Z'
        published_at:
          anyOf:
            - type: string
              format: date-time
              example: '2026-08-09T12:00:00.000Z'
            - type: 'null'
        cancelled_at:
          anyOf:
            - type: string
              format: date-time
              example: '2026-08-09T12:00:00.000Z'
            - type: 'null'
        missed_at:
          anyOf:
            - type: string
              format: date-time
              example: '2026-08-09T12:00:00.000Z'
            - type: 'null'
        receipts:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                example: rcpt_01JABCDEF
                description: Unique publication receipt ID.
              object:
                type: string
                const: receipt
              item_index:
                type: integer
                minimum: 0
                example: 0
              provider_object_id:
                type: string
                example: '1844029112345678901'
              url:
                anyOf:
                  - type: string
                    format: uri
                  - type: 'null'
              state:
                type: string
                enum:
                  - published
                  - processing
                  - failed
              published_at:
                anyOf:
                  - type: string
                    format: date-time
                    example: '2026-08-09T12:00:00.000Z'
                  - type: 'null'
            required:
              - id
              - object
              - item_index
              - provider_object_id
              - url
              - state
              - published_at
        attempts:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                example: att_01JABCDEF
                description: Unique publishing attempt ID.
              object:
                type: string
                const: publishing_attempt
              number:
                type: integer
                minimum: 1
              trigger:
                type: string
                enum:
                  - initial
                  - automatic-retry
                  - manual-retry
                  - provider-poll
              status:
                type: string
                enum:
                  - started
                  - succeeded
                  - failed
                  - ambiguous
              started_at:
                type: string
                format: date-time
                example: '2026-08-09T12:00:00.000Z'
              finished_at:
                anyOf:
                  - type: string
                    format: date-time
                    example: '2026-08-09T12:00:00.000Z'
                  - type: 'null'
              retry_safety:
                type: string
                enum:
                  - safe
                  - may_duplicate
              error:
                anyOf:
                  - type: object
                    additionalProperties: false
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                      retryable:
                        type: boolean
                      user_action:
                        type: string
                        enum:
                          - retry
                          - verify_provider
                          - reauthorize
                          - check_request
                    required:
                      - code
                      - message
                      - retryable
                      - user_action
                  - type: 'null'
              provider:
                type: object
                additionalProperties: false
                properties:
                  operation:
                    anyOf:
                      - type: string
                        maxLength: 500
                      - type: 'null'
                  request_id:
                    anyOf:
                      - type: string
                        maxLength: 500
                      - type: 'null'
                  status_code:
                    anyOf:
                      - type: integer
                        minimum: 100
                        maximum: 599
                      - type: 'null'
                  error_code:
                    anyOf:
                      - type: string
                        maxLength: 500
                      - type: 'null'
                  subcode:
                    anyOf:
                      - type: string
                        maxLength: 500
                      - type: 'null'
                required:
                  - operation
                  - request_id
                  - status_code
                  - error_code
                  - subcode
            required:
              - id
              - object
              - number
              - trigger
              - status
              - started_at
              - finished_at
              - retry_safety
              - error
              - provider
          description: Sanitized attempt history. Present only when `include=attempts`.
        destination:
          anyOf:
            - type: object
              additionalProperties: false
              properties:
                display_name:
                  type: string
                external_id:
                  type: string
                profile_image_url:
                  anyOf:
                    - type: string
                      format: uri
                    - type: 'null'
              required:
                - display_name
                - external_id
                - profile_image_url
            - type: 'null'
        assets:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                example: ast_01JABCDEF
                description: Unique asset ID.
              type:
                type: string
                enum:
                  - card
                  - video
                  - poster
                description: >-
                  Generic asset type. `video` does not select a provider
                  placement.
              label:
                type: string
              content_type:
                anyOf:
                  - type: string
                  - type: 'null'
              item_index:
                type: integer
                minimum: 0
                description: The zero-based body item that owns this asset.
            required:
              - id
              - type
              - label
              - content_type
              - item_index
      required:
        - id
        - object
        - group
        - channel
        - state
        - editable
        - terminal
        - action_required
        - next_action_at
        - retry_safety
        - available_actions
        - version
        - payload
        - asset_ids
        - destination_id
        - scheduled_at
        - time_zone
        - schedule_mode
        - queue_local_date
        - queue_window_id
        - attempt_count
        - deferred
        - last_error
        - created_at
        - updated_at
        - published_at
        - cancelled_at
        - missed_at
        - receipts
        - destination
        - assets
    Problem:
      type: object
      additionalProperties: false
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
          example: Request failed
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type: string
        instance:
          type: string
          format: uri
        code:
          type: string
          example: public_invalid_request
        category:
          type: string
          enum:
            - authentication
            - authorization
            - billing
            - conflict
            - internal
            - not_found
            - provider
            - rate_limit
            - validation
        request_id:
          type: string
          example: req_01JABCDEF
        retryable:
          type: boolean
        retry:
          type: object
          additionalProperties: false
          properties:
            safety:
              type: string
              enum:
                - safe
                - not_retryable
            after:
              anyOf:
                - type: integer
                  minimum: 0
                - type: 'null'
          required:
            - safety
            - after
        user_action:
          type: string
          enum:
            - check_request
            - contact_support
            - inspect_resource
            - reauthorize
            - retry
            - wait
        reason:
          type: string
          enum:
            - velocity
            - backlog
            - account-paused
        retry_at:
          anyOf:
            - type: string
              format: date-time
              example: '2026-08-09T12:00:00.000Z'
            - type: 'null'
        provider_requests_started:
          type: boolean
          const: false
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ProblemError'
      required:
        - type
        - title
        - status
        - detail
        - instance
        - code
        - category
        - request_id
        - retryable
        - retry
        - user_action
        - errors
      description: RFC 9457 problem details with stable OpenPMM fields.
      example:
        type: https://www.openpmm.com/docs/reference/errors#public_invalid_request
        title: Invalid request
        status: 400
        detail: The request body does not match the public contract.
        instance: urn:openpmm:request:req_01JABCDEF
        code: public_invalid_request
        category: validation
        request_id: req_01JABCDEF
        retryable: false
        retry:
          safety: not_retryable
          after: null
        user_action: check_request
        errors:
          - pointer: /posts/0/destination_id
            code: custom
            detail: Publishing an entry requires a destination.
    ProblemError:
      type: object
      additionalProperties: false
      properties:
        pointer:
          type: string
          example: /posts/0/destination_id
          description: JSON Pointer to the invalid request member.
        post_id:
          type: string
          example: send_01JABCDEF
          description: Unique Post ID.
        code:
          type: string
          example: custom
        detail:
          type: string
          example: Publishing requires a destination.
        channel:
          type: string
          enum:
            - bluesky
            - facebook
            - instagram
            - threads
            - mastodon
            - x
            - linkedin
            - tiktok
            - youtube
          example: x
        destination_id:
          anyOf:
            - type: string
              example: dest_01JABCDEF
              description: Unique destination ID.
            - type: 'null'
        destination_label:
          type: string
        asset_id:
          anyOf:
            - type: string
              example: ast_01JABCDEF
              description: Unique asset ID.
            - type: 'null'
        property:
          type: string
        media_kind:
          type: string
          enum:
            - image
            - video
        actual:
          anyOf:
            - $ref: '#/components/schemas/MediaMeasure'
            - type: 'null'
        required:
          $ref: '#/components/schemas/MediaRequirementSummary'
        allowed_actions:
          type: array
          items:
            type: string
            enum:
              - replace_asset
              - remove_destination
              - retry
        retryable:
          type: boolean
      required:
        - code
        - detail
    MediaMeasure:
      oneOf:
        - type: object
          additionalProperties: false
          properties:
            kind:
              type: string
              const: number
            value:
              type: number
            unit:
              type: string
          required:
            - kind
            - value
            - unit
        - type: object
          additionalProperties: false
          properties:
            kind:
              type: string
              const: text
            value:
              type: string
          required:
            - kind
            - value
        - type: object
          additionalProperties: false
          properties:
            kind:
              type: string
              const: boolean
            value:
              type: boolean
          required:
            - kind
            - value
    MediaRequirementSummary:
      oneOf:
        - type: object
          additionalProperties: false
          properties:
            kind:
              type: string
              const: range
            min:
              anyOf:
                - type: number
                - type: 'null'
            max:
              anyOf:
                - type: number
                - type: 'null'
            unit:
              type: string
            owner:
              type: string
              enum:
                - openpmm
                - provider
                - destination
          required:
            - kind
            - min
            - max
            - unit
            - owner
        - type: object
          additionalProperties: false
          properties:
            kind:
              type: string
              const: allowed
            allowed:
              type: array
              items:
                type: string
            owner:
              type: string
              enum:
                - openpmm
                - provider
                - destination
          required:
            - kind
            - allowed
            - owner
        - type: object
          additionalProperties: false
          properties:
            kind:
              type: string
              const: expected
            expected:
              type: string
            owner:
              type: string
              enum:
                - openpmm
                - provider
                - destination
          required:
            - kind
            - expected
            - owner
  responses:
    BadRequest:
      description: The request has invalid syntax, content, a cursor, or a header.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthenticated:
      description: Bearer authentication is missing or invalid.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
        WWW-Authenticate:
          $ref: '#/components/headers/WWWAuthenticate'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    PaymentRequired:
      description: The account subscription does not permit this operation.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Forbidden:
      description: The credential lacks the operation’s required scope.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotFound:
      description: >-
        The resource does not exist, or the API credential cannot use its
        workspace.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Conflict:
      description: >-
        The request conflicts with the current state. This error also occurs
        when different input uses an existing idempotency key or when OpenPMM
        cannot determine the result of an earlier request.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            idempotency_outcome_unknown:
              summary: The result of an earlier request is unknown
              value:
                type: >-
                  https://www.openpmm.com/docs/reference/errors#public_idempotency_outcome_unknown
                title: Mutation outcome unknown
                status: 409
                detail: >-
                  The earlier request outcome is unknown. Inspect the affected
                  resource before you create new work.
                instance: urn:openpmm:request:req_01JABCDEF
                code: public_idempotency_outcome_unknown
                category: conflict
                request_id: req_01JABCDEF
                retryable: false
                retry:
                  safety: not_retryable
                  after: null
                user_action: inspect_resource
                errors: []
            post_group_channel_conflict:
              summary: The group already contains the requested channel
              value:
                type: >-
                  https://www.openpmm.com/docs/reference/errors#public_post_group_channel_conflict
                title: Request conflict
                status: 409
                detail: >-
                  This group already contains a draft Post for one or more
                  requested channels. Update or publish the existing draft
                  before you create another one.
                instance: urn:openpmm:request:req_01JABCDEF
                code: public_post_group_channel_conflict
                category: conflict
                request_id: req_01JABCDEF
                retryable: false
                retry:
                  safety: not_retryable
                  after: null
                user_action: check_request
                errors: []
    PayloadTooLarge:
      description: The request body exceeds the 1 MiB edge limit.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: >-
              https://www.openpmm.com/docs/reference/errors#public_payload_too_large
            title: Payload too large
            status: 413
            detail: The request body exceeds the 1 MiB limit.
            instance: urn:openpmm:request:req_01JABCDEF
            code: public_payload_too_large
            request_id: req_01JABCDEF
            retryable: false
            errors: []
    UnprocessableContent:
      description: The request has valid syntax, but OpenPMM cannot publish or schedule it.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    RateLimited:
      description: The request exceeded the rate limit.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
        text/html:
          schema:
            type: string
    InternalError:
      description: OpenPMM could not complete the request because of an internal error.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    BadGateway:
      description: A social provider did not return a valid response.
      headers:
        OpenPMM-Request-Id:
          $ref: '#/components/headers/OpenPMMRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: OpenPMM API key
      description: 'Send an account API key in the `Authorization: Bearer <key>` header.'

````