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

# Create post

> Create a draft targeting one or more social accounts. Returns 201.

Always a `draft`. Schedule or publish with [`PUT /posts/{id}`](/docs/api-reference/posts/update).

<Note>
  `custom_content` / `custom_media` are siblings of `meta`. Omit or send `null` to inherit the root. `""` / `[]` is an explicit empty override. Required-to-publish meta (Pinterest `board_id`, TikTok `privacy_level`, Discord `channel_id`) is only enforced on `scheduled` / `publishing`. Full keys: [Per-platform meta](/docs/api-reference/posts/update#per-platform-meta).
</Note>

Media `url` values must be a [`public_url`](/docs/guides/media) from presign. External URLs return **422**.

## Request

REST requires at least one `platforms[]` entry (`min:1`). MCP `create-post-tool` may omit `platforms` (every connected account is created disabled until you enable rows).

<ParamField body="platforms" type="array" required>
  At least one entry (`min:1`).

  <Expandable>
    <ParamField body="social_account_id" type="string" required>
      UUID of a social account on this Connect account.
    </ParamField>

    <ParamField body="content_type" type="string" required>
      Must match that account's platform. See [content types](/docs/guides/posts#content-types). MCP: `list-content-types-tool`.
    </ParamField>

    <ParamField body="custom_content" type="string">
      Caption for this platform only. Max 10 000 at the API; per-network caps run against this value when `scheduled_at` is set.
    </ParamField>

    <ParamField body="custom_media" type="array">
      Same item shape as root `media`. Checked against **this** platform only.
    </ParamField>

    <ParamField body="meta" type="object">
      Optional per-platform settings. Unknown keys are dropped.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="content" type="string">
  Shared caption. Max **10 000**. Defaults to empty. For Pinterest this is the pin description.
</ParamField>

<ParamField body="media" type="array">
  Shared media. Each item needs `url` (the presign `public_url`). Optional `meta.alt_text` (max 2000).
</ParamField>

<ParamField body="scheduled_at" type="string">
  ISO 8601 in the future. Stored on the draft; status stays `draft`. Omit for `scheduled_at: null`.
</ParamField>

## Response

`201` with the created post. Shape matches [`GET /posts/{id}`](/docs/api-reference/posts/get).

<RequestExample>
  ```bash theme={null}
  curl -X POST https://connect.trypost.it/api/posts \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "content": "New pin from the Connect API",
      "media": [],
      "platforms": [
        {
          "social_account_id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
          "content_type": "pinterest_pin",
          "custom_content": "Pin description for Pinterest only",
          "meta": {
            "board_id": "1234567890123456789",
            "title": "Summer lookbook",
            "link": "https://example.com/shop/summer"
          }
        }
      ],
      "scheduled_at": "2026-05-10T15:30:00Z"
    }'
  ```
</RequestExample>
