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

# Update Post

> Update a scheduled or pending post

Update the caption, media, accounts, schedule, or external metadata for a scheduled/pending post.

<Note>
  Only posts in `draft`, `pending`, `scheduled`, `retry`, or `failed` status can be edited. Posted,
  partial, or canceled posts are immutable.
</Note>

## Path Parameters

<ParamField path="id" type="string" required>
  The ID of the post to update.
</ParamField>

## Body Parameters

<ParamField body="caption" type="string">
  Optional replacement caption. At least one field in the body is required; empty payloads are
  rejected with `422 invalid_payload`.

  <Warning>
    Target-specific limit. Hosted Accounts targets cap captions at 500 characters. BYO caps follow
    the selected platform and media type: Facebook 63,206; Instagram 2,200; TikTok 2,200 for video
    captions / 4,000 for photo-post descriptions; LinkedIn 3,000; Pinterest 800; YouTube 5,000
    bytes.
  </Warning>
</ParamField>

<ParamField body="media" type="object | null">
  Optional replacement media payload. Follows the same structure as [Create
  Post](/api-reference/create-post). Pass `null` to clear media and make the post text-only.
  Text-only updates fail when any selected account requires media.
</ParamField>

<ParamField body="accounts" type="array">
  Optional list of account objects (max 10): `[{ "id": "<uuid-from-/accounts>" }]`. **Replaces**
  the previous targeting list completely.
</ParamField>

<ParamField body="settings" type="object">
  Optional canonical provider settings update keyed by provider/platform. Unknown provider keys fail
  closed with `422 invalid_payload`. Partial `settings.<provider>` patches **merge** with stored
  values (they do not replace the whole provider block). Use the field tables in
  [Create Post](/api-reference/create-post#provider-settings), not the dashboard `settings_schema`
  from [`GET /accounts`](/api-reference/get-accounts) — composer field names such as `coverUrl` are
  rejected by the Partner API.
  For YouTube, send `settings.youtube.title` to set the video title explicitly; if omitted, Genviral
  derives the title from the first non-empty caption line.
</ParamField>

<ParamField body="tiktok" type="object | null">
  Optional TikTok settings update. Send TikTok-specific fields here (top-level), not under
  `settings.tiktok`. Pass `null` to clear stored TikTok settings from the post.
  <Warning>Supported only when every targeted account is a TikTok BYO account.</Warning>

  <Expandable title="TikTok Settings">
    <ParamField body="title" type="string">
      Optional TikTok title override. Video posts: max 2,200 UTF-16 runes. Photo/slideshow posts:
      max 90 UTF-16 runes.
    </ParamField>

    <ParamField body="description" type="string">
      Optional TikTok description override. Photo/slideshow posts: max 4,000 UTF-16 runes. For video
      posts, Genviral keeps this field for compatibility and uses it as a fallback source when
      deriving the TikTok title if `title` is blank.
    </ParamField>

    <ParamField body="post_mode" type="string">
      `DIRECT_POST` or `MEDIA_UPLOAD` (uploads to TikTok inbox/drafts).
    </ParamField>

    <ParamField body="privacy_level" type="string">
      Optional privacy level (`PUBLIC_TO_EVERYONE`, `MUTUAL_FOLLOW_FRIENDS`, `FOLLOWER_OF_CREATOR`,
      `SELF_ONLY`).
    </ParamField>

    <ParamField body="disable_comment" type="boolean">
      Optional comment toggle.
    </ParamField>

    <ParamField body="disable_duet" type="boolean">
      Optional duet toggle (video posts).
    </ParamField>

    <ParamField body="disable_stitch" type="boolean">
      Optional stitch toggle (video posts).
    </ParamField>

    <ParamField body="video_cover_timestamp_ms" type="integer">
      Optional video cover frame offset in milliseconds (video posts, `DIRECT_POST` only). TikTok
      uses this frame as the video thumbnail.
    </ParamField>

    <ParamField body="music_usage_confirmation" type="boolean">
      Confirms the user has accepted TikTok's music-usage terms for this post. Preferred Partner API
      field.
    </ParamField>

    <ParamField body="user_consent" type="boolean">
      Legacy alias for `music_usage_confirmation`.
    </ParamField>

    <ParamField body="is_commercial" type="boolean">
      Optional commercial-content flag.
    </ParamField>

    <ParamField body="is_your_brand" type="boolean">
      Optional branded-content flag for own brand.
    </ParamField>

    <ParamField body="is_branded_content" type="boolean">
      Optional branded-content flag for third-party promotion.
    </ParamField>

    <ParamField body="auto_add_music" type="boolean">
      Optional TikTok auto-music toggle (photo posts).
    </ParamField>
  </Expandable>

  Pass `null` to clear stored TikTok settings from the post.
</ParamField>

<ParamField body="pinterest" type="object | null">
  Optional Pinterest settings update. Send Pinterest-specific fields here (top-level), not under
  `settings.pinterest`. Pass `null` to clear stored Pinterest settings from the post.
  <Warning>Supported only when at least one targeted account is a Pinterest account.</Warning>

  <Expandable title="Pinterest Settings">
    <ParamField body="board_id" type="string">
      Optional Pinterest board ID (max 128 chars).
    </ParamField>

    <ParamField body="title" type="string">
      Optional Pinterest pin title override (max 100 chars).
    </ParamField>

    <ParamField body="link" type="string">
      Optional destination URL (max 2,048 chars).
    </ParamField>

    <ParamField body="tags" type="string[]">
      Optional Pinterest topic tags (up to 30). Multi-word tags are supported. Genviral appends
      these tags to the Pinterest description, so `caption + appended tags` must still fit
      Pinterest's 800-character description limit.
    </ParamField>
  </Expandable>

  Pass `null` to clear stored Pinterest settings from the post.
</ParamField>

<Note>
  TikTok and Pinterest use top-level `tiktok` / `pinterest` on create and update (same as Create
  Post). Other providers use `settings.<provider>`. Only include settings for providers present in
  the selected accounts.
</Note>

<ParamField body="scheduled_at" type="string | null">
  Optional ISO 8601 datetime **with timezone offset**. Pass `null` to push the post back into the
  immediate publish queue (`status: pending`). For true scheduled times, the value must be **at
  least 2 minutes** in the future.
</ParamField>

<ParamField body="external_id" type="string">
  Not mutable after creation. Partner API treats `external_id` as the create-time idempotency key,
  so PATCH requests that try to change it return `409 external_id_immutable`.
</ParamField>

<ParamField body="music_url" type="string">
  Optional TikTok post URL for background music (e.g.,
  `https://www.tiktok.com/@genviral/video/1234567890`). Pass `null` to remove existing music without
  changing media. This field is TikTok-only. Instagram's official publishing API does not support
  music/sound selection for carousels or Reels, so update requests that include Instagram accounts
  with `music_url` will be rejected.
</ParamField>

## Limits

* Caption: enforced against the targeted accounts. Hosted Accounts targets stay at 500 characters. BYO caps follow platform limits: Facebook 63,206; Instagram 2,200; TikTok 2,200 for video captions and 4,000 for photo-post descriptions; LinkedIn 3,000; Pinterest 800; YouTube 5,000 bytes.
* Text-only: set `media` to `null` or omit media while updating other fields;
  every selected account must advertise `text_only` in `/accounts`
  capabilities.
* Video: MP4/MOV/M4V/AVI, under 100MB. If duration metadata is present, we enforce 15–60 seconds; when duration is missing we proceed with a warning. \~9:16 aspect recommended.
* Slideshow: 1–35 images, JPG/JPEG/PNG, each under 5MB. \~9:16 aspect recommended.
* Music: TikTok-only. Instagram's official API does not support music/sound selection for carousel posts or Reels, so requests with `music_url` are rejected when any Instagram account is selected.
* TikTok settings: supported only when all selected accounts are TikTok BYO accounts.
* `tiktok.post_mode = MEDIA_UPLOAD`: supported only for `media.type = slideshow` (photo posts).
* `tiktok.video_cover_timestamp_ms`: supported for video `DIRECT_POST` requests.
* Pinterest settings: supported only when at least one selected account is Pinterest.
* `pinterest.tags`: up to 30 tags, each 1–100 characters (spaces allowed). Tags are appended to the final Pinterest description, which still must fit 800 characters.
* Provider settings: send canonical settings under `settings.<provider>`.
  Unknown provider keys are rejected with `422 invalid_payload`.

See [Create Post provider settings](/api-reference/create-post#provider-settings)
for the current per-platform field reference.

<RequestExample>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url https://www.genviral.io/api/partner/v1/posts/11111111-1111-1111-1111-111111111111 \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '{
    "caption": "Updated caption",
    "media": null,
    "music_url": null,
    "scheduled_at": "2025-03-01T17:00:00Z"
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "ok": true,
    "code": 200,
    "message": "Post updated",
    "data": {
      "id": "11111111-1111-1111-1111-111111111111",
      "status": "scheduled",
      "scheduled_at": "2025-03-01T17:00:00Z",
      "warnings": [
        {
          "field": "media",
          "message": "Video size metadata is missing",
          "code": "VIDEO_METADATA_MISSING"
        }
      ]
    }
  }
  ```
</ResponseExample>

<Note>
  Update responses can include `warnings` about missing media metadata. They are informational so
  you can re-upload media before Hosted Accounts reject it.
</Note>

## Error Responses

* `400 invalid_json` - body is not valid JSON
* `422 invalid_payload` - no editable fields provided or schema validation failed
* `400 unknown_accounts` - one or more provided accounts are outside the authenticated key scope
* `400 missing_accounts` - resolved account list is empty after validation
* `400 validation_failed` - post is immutable or media/music/caption rules failed
* `400 invalid_music_url` or `400 media_unreachable` - TikTok/music URLs failed validation
* `401` - authentication failed (missing/invalid/revoked token)
* `402 subscription_required` - active Creator/Professional/Business plan required
* `403 tier_not_allowed` - Scheduler tier cannot use Partner API
* `409 external_id_immutable` - PATCH tried to change `external_id`
* `403 subscription_required` - hosted TikTok posting without an active TikTok virtual subscription
* `500 update_failed` - Database update failed unexpectedly
