<!-- https://cutedyno.com/docs/api/update-post -->

# Update a post

`PUT https://api.cutedyno.com/v1/posts/{id}`

Edits content, targets, or schedule. Published and in-flight posts cannot be edited.



Required permission: `posts:write`

Accepts `profileId` to target a specific profile. Omit it to use the key’s home profile.

Required permission: `posts:write`

MCP tool: `update_post`

## Path parameters

- `id` (string, required) — Post id.

## Body

- `profileId` (string) — Profile to act on. Defaults to the profile the API key was created in.
- `content` (string) — Post text. Used as the caption for image and video posts. Required unless the post is a draft with media.
- `media` (MediaItem[]) — Images or a single video. Get URLs from POST /v1/media/upload. Content type is inferred: a video wins, otherwise images, otherwise text.
- `accountIds` (string[]) — `id` values from GET /v1/accounts; `platformAccountId` also works. Required to schedule or publish, omit to save an unassigned draft.
- `scheduledAt` (string) — ISO 8601 datetime, for example 2026-08-01T12:00:00Z.
- `publishNow` (boolean) — Queue for immediate publishing. Cannot be combined with scheduledAt.
- `platforms` (object) — Per-platform options, applied only to accounts on that platform. Everything here is optional; sensible defaults apply.
- `approvers` (string[]) — Emails to send approval requests to, used only when the profile or key requires approval. Defaults to the key owner.

## Request

```bash
curl -X PUT "https://api.cutedyno.com/v1/posts/POST_ID" \
  -H "Authorization: Bearer $CUTEDYNO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "profileId": "profile_a1b2c3d4",
  "content": "Shipping today.",
  "media": [
    {
      "type": "image",
      "url": "https://cdn.example.com/media/launch.jpg"
    }
  ],
  "accountIds": [
    "string"
  ],
  "scheduledAt": "string",
  "publishNow": false,
  "platforms": {
    "facebook": {
      "privacy": {
        "value": "PUBLIC"
      },
      "place": "string",
      "alt_text_custom": "string",
      "no_story": false
    },
    "instagram": {
      "location_id": "location_id_a1b2c3d4",
      "thumbnail_url": "https://cdn.example.com/media/launch.jpg",
      "collaborators": [
        "string"
      ]
    },
    "tiktok": {
      "title": "string",
      "privacy_level": "PUBLIC_TO_EVERYONE",
      "disable_comment": false,
      "disable_duet": false,
      "disable_stitch": false,
      "video_cover_timestamp_ms": 0,
      "brand_content_toggle": false,
      "brand_organic_toggle": false,
      "is_aigc": false,
      "auto_add_music": false,
      "upload_as_draft": false
    },
    "linkedin": {
      "title": "string",
      "visibility": "PUBLIC"
    },
    "youtube": {
      "title": "string",
      "description": "string",
      "privacyStatus": "public",
      "tags": [
        "string"
      ]
    }
  },
  "approvers": [
    "string"
  ]
}'
```

```typescript
import { CuteDyno } from '@cutedyno/node';

const cutedyno = new CuteDyno();

const result = await cutedyno.posts.update('POST_ID', {
  profileId: "profile_a1b2c3d4",
  content: "Shipping today.",
  media: [
    {
      type: "image",
      url: "https://cdn.example.com/media/launch.jpg"
    }
  ],
  accountIds: [
    "string"
  ],
  scheduledAt: "string",
  publishNow: false,
  platforms: {
    facebook: {
      privacy: {
        value: "PUBLIC"
      },
      place: "string",
      alt_text_custom: "string",
      no_story: false
    },
    instagram: {
      location_id: "location_id_a1b2c3d4",
      thumbnail_url: "https://cdn.example.com/media/launch.jpg",
      collaborators: [
        "string"
      ]
    },
    tiktok: {
      title: "string",
      privacy_level: "PUBLIC_TO_EVERYONE",
      disable_comment: false,
      disable_duet: false,
      disable_stitch: false,
      video_cover_timestamp_ms: 0,
      brand_content_toggle: false,
      brand_organic_toggle: false,
      is_aigc: false,
      auto_add_music: false,
      upload_as_draft: false
    },
    linkedin: {
      title: "string",
      visibility: "PUBLIC"
    },
    youtube: {
      title: "string",
      description: "string",
      privacyStatus: "public",
      tags: [
        "string"
      ]
    }
  },
  approvers: [
    "string"
  ]
});
console.log(result);
```

```python
import os
import requests

url = "https://api.cutedyno.com/v1/posts/POST_ID"
headers = {"Authorization": f"Bearer {os.environ['CUTEDYNO_API_KEY']}"}

payload = {
    "profileId": "profile_a1b2c3d4",
    "content": "Shipping today.",
    "media": [
        {
            "type": "image",
            "url": "https://cdn.example.com/media/launch.jpg"
        }
    ],
    "accountIds": [
        "string"
    ],
    "scheduledAt": "string",
    "publishNow": False,
    "platforms": {
        "facebook": {
            "privacy": {
                "value": "PUBLIC"
            },
            "place": "string",
            "alt_text_custom": "string",
            "no_story": False
        },
        "instagram": {
            "location_id": "location_id_a1b2c3d4",
            "thumbnail_url": "https://cdn.example.com/media/launch.jpg",
            "collaborators": [
                "string"
            ]
        },
        "tiktok": {
            "title": "string",
            "privacy_level": "PUBLIC_TO_EVERYONE",
            "disable_comment": False,
            "disable_duet": False,
            "disable_stitch": False,
            "video_cover_timestamp_ms": 0,
            "brand_content_toggle": False,
            "brand_organic_toggle": False,
            "is_aigc": False,
            "auto_add_music": False,
            "upload_as_draft": False
        },
        "linkedin": {
            "title": "string",
            "visibility": "PUBLIC"
        },
        "youtube": {
            "title": "string",
            "description": "string",
            "privacyStatus": "public",
            "tags": [
                "string"
            ]
        }
    },
    "approvers": [
        "string"
    ]
}

response = requests.put(url, json=payload, headers=headers)
response.raise_for_status()
print(response.json())
```

## Response 200

- `post` (Post, required)

```json
{
  "post": {
    "id": "a1b2c3d4-0000-4000-8000-000000000000",
    "status": "draft",
    "content": "Shipping today.",
    "contentType": "text",
    "media": [
      {
        "type": "image",
        "url": "https://cdn.example.com/media/launch.jpg"
      }
    ],
    "platforms": {},
    "scheduledAt": "string",
    "createdAt": "string",
    "updatedAt": "string",
    "completedAt": "string",
    "accounts": [
      {
        "id": "a1b2c3d4-0000-4000-8000-000000000000",
        "platformAccountId": "platformAccount_a1b2c3d4",
        "platform": "string",
        "name": "Acme Corp"
      }
    ],
    "results": [
      {
        "targetId": "target_a1b2c3d4",
        "platform": "facebook",
        "pageName": "Acme Corp",
        "status": "success",
        "result": null,
        "error": "string"
      }
    ],
    "completedTargets": 0,
    "failedTargets": 0,
    "totalTargets": 0
  }
}
```

## Errors

- `invalid_request` (400) — The request body or query string failed validation. The message names the offending field.
- `invalid_scheduled_at` (400) — scheduledAt could not be parsed as an ISO 8601 datetime, or it is in the past.
- `invalid_state_transition` (400) — The post is in a state that does not allow this operation, for example editing a post that already published.
- `invalid_api_key` (401) — The key does not exist, was revoked, or is malformed. Keys start with cdyn_live_.
- `account_not_allowed` (403) — The key is restricted to specific connected accounts and one of the supplied accountIds is not among them.
- `platform_not_allowed` (403) — The profile policy restricts which platforms may be posted to, and one of the target accounts is on a platform outside that list.
- `not_found` (404) — The resource does not exist inside the resolved profile.
- `rate_limit_exceeded` (429) — Too many requests for this key. Honour the Retry-After header before retrying.
- `internal_error` (500) — Something failed on our side. Retry with the same Idempotency-Key; report the requestId if it persists.