API reference

POST/v1/posts

Create a post

Creates a draft, schedules a post, or publishes immediately, depending on scheduledAt, publishNow, and draft.

Required permission: `posts:write`

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

Base URL
https://api.cutedyno.com
Permission
posts:write
Idempotency
Send an Idempotency-Key header so a retry cannot apply twice. How it works
MCP tool
create_post

Request

curl -X POST "https://api.cutedyno.com/v1/posts" \
  -H "Authorization: Bearer $CUTEDYNO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -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"
  ]
}'

Headers

Idempotency-Keystringoptional

A unique key so a retried request is not applied twice. Stored for 24 hours.

Body

profileIdstringoptional

Profile to act on. Defaults to the profile the API key was created in.

contentstringoptional

Post text. Used as the caption for image and video posts. Required unless the post is a draft with media.

MediaItem[]optional

Images or a single video. Get URLs from POST /v1/media/upload. Content type is inferred: a video wins, otherwise images, otherwise text.

accountIdsstring[]optional

`id` values from GET /v1/accounts; `platformAccountId` also works. Required to schedule or publish, omit to save an unassigned draft.

scheduledAtstringoptional

ISO 8601 datetime, for example 2026-08-01T12:00:00Z.

publishNowbooleanoptional

Queue for immediate publishing. Cannot be combined with scheduledAt.

objectoptional

Per-platform options, applied only to accounts on that platform. Everything here is optional; sensible defaults apply.

approversstring[]optional

Emails to send approval requests to, used only when the profile or key requires approval. Defaults to the key owner.

Response

Returns 201 with the following body.

objectrequired

Example

{
  "post": {
    "id": "a1b2c3d4-0000-4000-8000-000000000000",
    "status": "draft",
    "profileId": "profile_a1b2c3d4",
    "scheduledAt": "string",
    "approvers": [
      "string"
    ],
    "accounts": [
      {
        "id": "a1b2c3d4-0000-4000-8000-000000000000",
        "platformAccountId": "platformAccount_a1b2c3d4",
        "platform": "string",
        "name": "Acme Corp"
      }
    ]
  }
}

Errors

Failures use the standard error envelope. Branch on code, never on the message.

StatusCodeWhen it happens
400invalid_requestThe request body or query string failed validation. The message names the offending field.
400invalid_scheduled_atscheduledAt could not be parsed as an ISO 8601 datetime, or it is in the past.
400key_not_linked_to_userPublishing records a human actor. Recreate the key from the dashboard so it carries an owner.
401invalid_api_keyThe key does not exist, was revoked, or is malformed. Keys start with cdyn_live_.
402trial_expiredThe account trial ended. Billing affects every profile at once, so alert an operator instead of retrying.
403account_not_allowedThe key is restricted to specific connected accounts and one of the supplied accountIds is not among them.
403platform_not_allowedThe profile policy restricts which platforms may be posted to, and one of the target accounts is on a platform outside that list.
403approval_requiredThis profile or key forces posts through review, and no approver could be determined. Supply approvers, or recreate the key so it carries an owner.
403daily_post_limitThe key has a maxPostsPerDay cap and it has been reached. The cap resets at midnight UTC.
403plan_limitA plan quota was exhausted. The response carries entitlement, usage, and limit so you can surface the reason.
404no_accounts_connectedThe profile has no connected social accounts yet. Run the connect flow first.
404accounts_not_foundNone of the supplied accountIds matched a connected account in this profile.
429rate_limit_exceededToo many requests for this key. Honour the Retry-After header before retrying.
500internal_errorSomething failed on our side. Retry with the same Idempotency-Key; report the requestId if it persists.