Posts

Update a post

Update a post that has not been published yet. Every field is optional - only the fields present in the request body are changed. Editable fields are the post body (content or containers, including each container's media), the publish time (scheduledAt), the isDraft flag, and the platform-specific configuration provided as top-level keys named after the network (tiktok, youtube, instagram, threads, google_business, pinterest, linkedin, facebook, vimeo, reddit, x, bluesky), including each block's per-network content override. Platform config is merged per network and per field within a network: sending only tiktok leaves the stored YouTube configuration alone, and sending only tiktok.disableComment leaves the stored TikTok postMode and privacyLevel alone. Sending content or containers replaces the post's containers and their media entirely - there is no per-container patching. The set of social accounts a post targets cannot be changed (the accounts carry per-account publish state); delete the post and create a new one to publish to different accounts. Changing scheduledAt reschedules the queued publishing job: the existing job is cancelled and a new one is created for the new time, and the response reports rescheduled: true. Setting isDraft to true cancels the queued job without creating a new one. Posts that are already published (fully or for any single account) are rejected with 409, because editing the stored post does not change anything already live on the platforms. When the request replaces the containers of a post that targets a Threads account, each container must be 500 characters or fewer or the request is rejected with 400 (a threads.content override is checked in place of the shared body); a request that leaves the containers alone only length-checks the <network>.content overrides it sends. To retry a quota-denied YouTube destination on a partially published post, create a new YouTube-only post targeting that failed account. Rescheduling does not reserve upload capacity; admission is checked when the new attempt executes. Google Business EVENT and OFFER posts require an event title, startDate, startTime, endDate and endTime. CALL buttons omit callToAction.url; other action types require it. Google ignores callToAction on OFFER posts.

patch/v1/posts/{id}

Request

  • Base URL: https://api.outstand.so
  • URL: https://api.outstand.so/v1/posts/{id}
  • Auth: none declared

Path parameters

idstring required

Request body

contentstring

Simple text content for the post. Use this for single-container posts. Either 'content' or 'containers' must be provided. If you use 'containers', the first container will be the root container and the rest will be published as replies to the root container. Threads rejects content longer than 500 characters, so a post targeting a Threads account (including when cross-posting alongside other networks) is rejected with 400 if it exceeds that - unless threads.content supplies a Threads-only body, which is what gets checked instead. To publish different text on one network, put content inside that network's block (e.g. linkedin.content); this field is then the fallback for every network without one.

processMediaboolean

Opt in to automatic video processing. When true, video media is inspected and re-encoded to each target network's requirements (container, codec, resolution, frame rate and file size) before publishing, and the correct rendition is sent to each network. Leave unset to publish the file exactly as supplied. Billed per rendition produced, by output duration in 10-second blocks (rounded up, minimum one block per rendition); validation and inspection are always free. Has no effect on posts without video media.

scheduledAtstring date-time nullable

New ISO 8601 timestamp for when the post should be published. Changing this cancels the queued publishing job and creates a new one for the new time. Pass null to clear the schedule - the post is then published on the next queued run. Omit the field to leave the schedule untouched. The maximum time in the future is 30d - a later timestamp is rejected with 400 and the post is left unchanged.

isDraftboolean

Whether the post is a draft. Setting this to true cancels any queued publishing job; setting it back to false re-queues the post for its scheduled time (or immediately when there is no scheduledAt).

Example request

{
  "containers": [
    {
      "content": "Our newest feature is live! Check it out 🚀",
      "media": [
        {
          "url": "https://example.com/feature.png",
          "filename": "feature.png"
        }
      ]
    }
  ],
  "content": "Excited to announce our latest update!",
  "threads": {
    "content": "A more conversational take for Threads",
    "countries": [
      "US",
      "DK"
    ],
    "reply_control": "accounts_you_follow"
  },
  "instagram": {
    "locationId": "1234567890",
    "reelThumbOffset": 3240
  },
  "youtube": {
    "content": "A longer description for the YouTube video.",
    "isShort": true,
    "categoryId": "1234567890",
    "privacyStatus": "public",
    "madeForKids": true,
    "containsSyntheticMedia": true,
    "tags": [
      "tag1",
      "tag2"
    ],
    "title": "My new video",
    "thumbnailUrl": "https://cdn.example.com/video-thumbnail.jpg"
  },
  "tiktok": {
    "content": "Hook-first caption for TikTok",
    "postMode": "MEDIA_UPLOAD",
    "privacyLevel": "PUBLIC_TO_EVERYONE",
    "title": "Summer collection drop",
    "description": "Our new summer collection is here. Swipe through to see every look.",
    "videoCoverTimestampMs": 3500
  },
  "google_business": {
    "content": "Local-audience wording for Google Business.",
    "topicType": "STANDARD",
    "callToAction": {
      "actionType": "LEARN_MORE",
      "url": "https://example.com"
    },
    "event": {
      "title": "Grand Opening",
      "startDate": {
        "year": 2026,
        "month": 3,
        "day": 15
      },
      "startTime": {
        "hours": 9,
        "minutes": 0
      },
      "endDate": {
        "year": 2026,
        "month": 3,
        "day": 15
      },
      "endTime": {
        "hours": 17,
        "minutes": 0
      }
    },
    "offer": {
      "couponCode": "SAVE20",
      "redeemOnlineUrl": "https://example.com/redeem",
      "termsConditions": "Valid until March 31, 2026."
    }
  },
  "pinterest": {
    "content": "Pin description written for Pinterest search.",
    "board_id": "123456789",
    "cover_image_url": "https://example.com/cover.jpg",
    "link": "https://example.com/product",
    "alt_text": "A red dress on a model",
    "title": "New Summer Collection"
  },
  "vimeo": {
    "content": "Description for the Vimeo upload."
  },
  "linkedin": {
    "content": "A more professional, detailed version for LinkedIn.",
    "article": {
      "source": "https://example.com/blog/my-article",
      "title": "How We Scaled to 1M Users",
      "description": "A deep dive into our infrastructure journey.",
      "thumbnailUrl": "https://example.com/og-image.png"
    },
    "mentions": [
      {
        "urn": "urn:li:organization:1337",
        "text": "LinkedIn"
      }
    ],
    "caption": "Behind the scenes at our Berlin office"
  },
  "facebook": {
    "content": "Facebook-specific wording for the Page post.",
    "mentions": [
      {
        "pageId": "123456789",
        "text": "Outstand"
      }
    ],
    "publishAsStory": true,
    "publishAsReel": true
  },
  "reddit": {
    "content": "Markdown body written for the subreddit.",
    "subreddit": "programming",
    "title": "We built a unified social media API",
    "url": "https://example.com/blog/launch",
    "flairId": "c4acd8f2-9e2f-11eb-8000-0e3e6a4e8e8a",
    "flairText": "Discussion",
    "sendReplies": true
  },
  "x": {
    "content": "Short, punchy version for X"
  },
  "bluesky": {
    "content": "A version for Bluesky, within 300 characters"
  },
  "processMedia": true,
  "scheduledAt": "2026-03-01T09:00:00Z"
}

Response

Post updated successfully

successboolean required

Whether the post update was successful

warningsstring[]

Non-fatal warnings about the request. Used to report keys in the request body that were not recognised and were therefore ignored - both top-level keys and keys inside a platform-config block. Unrecognised keys are dropped before the post is stored, so a warning here means the change you sent is not in effect. Present only when there is at least one warning.

rescheduledboolean

Present when the update changed the publishing schedule. True when the queued publishing job was cancelled and re-created for the new time. Absent when the schedule was untouched.

Example response

{
  "success": true,
  "warnings": [
    "Ignored unrecognised key 'privacy_level' in 'tiktok'. Did you mean 'privacyLevel'?"
  ],
  "rescheduled": true,
  "post": {
    "id": "9dyJS",
    "orgId": "abc123",
    "publishedAt": null,
    "scheduledAt": "2025-09-20T14:00:00Z",
    "isDraft": false,
    "createdAt": "2025-01-15T10:30:00Z",
    "scheduled": true,
    "socialAccounts": [
      {
        "id": "Kx7vQ",
        "nickname": "My Company",
        "network": "x",
        "username": "mycompany"
      }
    ],
    "containers": [
      {
        "id": "8xKmL",
        "content": "Check out our new product launch! #excited",
        "media": [
          {
            "id": 123,
            "url": "https://media.yoursite.com/images/launch.jpg",
            "filename": "launch-photo.jpg"
          }
        ]
      }
    ]
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.