---
title: "Create post"
method: POST
path: "/api/posts"
tags: ["Posts"]
---

# Create post

`POST /api/posts`

## Request

- Base URL: `https://api.postproxy.dev`
- URL: `https://api.postproxy.dev/api/posts`
- Auth: HTTP bearer

Creates a new post and publishes it to the specified platforms. Set draft to true to create a draft that won't publish until reviewed.

## Query parameters

- `profile_group_id` string

## Headers

- `Idempotency-Key` string

## Request body

- PostCreateRequest: Request body for creating a post. Some platforms require media (Instagram, TikTok, YouTube); some platforms require text content.
  - `post` object
    - `body` string: Text content of the post
    - `scheduled_at` string, date-time: ISO 8601 timestamp to schedule the post. Do not pass together with queue_id — the queue determines the scheduled time automatically
    - `draft` boolean: If true, creates a draft that won't publish until reviewed
  - `profiles` string[], required: Array of profile IDs or platform names (e.g. "twitter", "instagram" — uses the first connected profile for that platform). All resolved profiles must belong to the same profile group.
  - `media` string[]: Array of media URLs, base64 data URIs, or file uploads (multipart)
  - `platforms` object: Platform-specific parameters, keyed by platform name (e.g. instagram, youtube). See Platform Parameters docs for all available options.
  - `thread` PostThreadItemRequest[]: Array of thread child posts. Threads are only supported on X (Twitter) and Threads; other platforms return a 422.
    - `body` string, required: Text content for this thread post
    - `media` string[]: Array of media URLs (same format as top-level media)
  - `profile_group_id` string: ID of the profile group to resolve profiles against. If omitted, platform names resolve in the default group (first one on the account) and profile IDs are looked up across all groups your API key / user can access
  - `queue_id` string: Queue ID — adds the post to a queue. The queue must belong to the same profile group as the resolved profiles
  - `queue_priority` 'high' | 'medium' | 'low': Queue priority (default: medium)

## Response `201`

Post created

- Post: A social media post with per-platform posting results.
  - `id` string: Unique post identifier (id)
  - `body` string: Post body/text content
  - `status` 'draft' | 'processing' | 'processed' | 'scheduled' | 'media_processing_failed': Post-level status
  - `source` 'postproxy' | 'imported': Origin of the post: postproxy (created via app or API) or imported (imported from a connected platform)
  - `draft` boolean: Whether the post is a draft
  - `scheduled_at` string, date-time, nullable: ISO 8601 timestamp if scheduled, null otherwise
  - `created_at` string, date-time: ISO 8601 timestamp of creation
  - `queue_id` string, nullable: Queue ID if the post belongs to a queue
  - `queue_priority` 'high' | 'medium' | 'low' | 'null', nullable: Priority level if in a queue
  - `media` PostMedia[]: Array of media attachment objects
    - `id` string: Unique attachment identifier (id)
    - `status` 'pending' | 'processed' | 'failed': Processing status
    - `error_message` string, nullable: Error details if processing failed
    - `content_type` string: MIME type (e.g. image/jpeg, video/mp4)
    - `source_url` string, nullable: Original source URL if media was provided as a URL
    - `url` string, nullable: Hosted URL of the processed file (null if not yet processed)
    - `platforms` PostMediaPlatformError[]: Per-platform formatting/upload errors for this attachment. Only included when at least one platform had an error processing this specific media file; omitted when there are no platform-level errors
      - `platform` string: Network identifier (instagram, twitter, etc.)
      - `status` string: Per-platform attachment status
      - `error` string: Error summary for this attachment on this platform
      - `error_details` PostErrorDetails: Structured platform error details.
        - `platform_error_code` string, nullable: Error code returned by the platform API
        - `platform_error_subcode` string, nullable: Error subcode returned by the platform API
        - `platform_error_message` string, nullable: Error message returned by the platform API
        - `postproxy_note` string, nullable: Additional context from Postproxy about the error
  - `platforms` PostPlatform[]: Array of platform-specific posting results. For thread posts, this only describes the parent — each thread item carries its own platforms array.
    - `platform` 'facebook' | 'instagram' | 'tiktok' | 'linkedin' | 'youtube' | 'twitter' | 'threads' | 'pinterest': Platform identifier
    - `profile_id` string: ID of the connected profile this platform entry was posted to
    - `profile_name` string: Display name of the connected profile
    - `status` string: Platform posting status: processing, published, failed, pending_deletion, deleted
    - `params` object, nullable: Platform-specific parameters used for this post
    - `error` string, nullable: Error summary (null on success)
    - `error_details` PostErrorDetails: Structured platform error details.
      - `platform_error_code` string, nullable: Error code returned by the platform API
      - `platform_error_subcode` string, nullable: Error subcode returned by the platform API
      - `platform_error_message` string, nullable: Error message returned by the platform API
      - `postproxy_note` string, nullable: Additional context from Postproxy about the error
    - `attempted_at` string, date-time, nullable: ISO 8601 timestamp of posting attempt
    - `permalink` string, nullable: Direct URL to the published post on the platform. Null if not published or permalink is unavailable
    - `insights` object: Engagement metrics (when available)
      - `impressions` integer: Number of impressions/views
      - `on` string, date-time: ISO 8601 timestamp when insights were captured
    - `attachments` PostPlatformAttachment[]: Platform-level files such as the video cover. Only returned by GET /posts/{id}, and omitted when there are none. For imported posts the cover comes from the platform (Instagram Reels, TikTok and LinkedIn videos). Imported TikTok posts have an empty media array, so use the cover as the thumbnail.
      - `id` string: Unique attachment identifier
      - `type` 'cover': Attachment type
      - `status` 'pending' | 'processed' | 'failed': Processing status
      - `content_type` string, nullable: MIME type of the file (e.g. image/jpeg)
      - `url` string, nullable: Hosted URL of the processed file (null until processed)
  - `thread` PostThreadChild[]: Array of thread child posts (only present for thread posts). Each item carries its own platforms array.
    - `id` string: Unique identifier (id) of the child post
    - `body` string: Text content of the child post
    - `media` PostMedia[]: Array of media attachment objects
      - `id` string: Unique attachment identifier (id)
      - `status` 'pending' | 'processed' | 'failed': Processing status
      - `error_message` string, nullable: Error details if processing failed
      - `content_type` string: MIME type (e.g. image/jpeg, video/mp4)
      - `source_url` string, nullable: Original source URL if media was provided as a URL
      - `url` string, nullable: Hosted URL of the processed file (null if not yet processed)
      - `platforms` PostMediaPlatformError[]: Per-platform formatting/upload errors for this attachment. Only included when at least one platform had an error processing this specific media file; omitted when there are no platform-level errors
        - `platform` string: Network identifier (instagram, twitter, etc.)
        - `status` string: Per-platform attachment status
        - `error` string: Error summary for this attachment on this platform
        - `error_details` PostErrorDetails: Structured platform error details.
          - `platform_error_code` string, nullable: Error code returned by the platform API
          - `platform_error_subcode` string, nullable: Error subcode returned by the platform API
          - `platform_error_message` string, nullable: Error message returned by the platform API
          - `postproxy_note` string, nullable: Additional context from Postproxy about the error
    - `platforms` PostPlatform[]: Per-platform delivery results for this thread item (status, permalink, error, error_details)
      - `platform` 'facebook' | 'instagram' | 'tiktok' | 'linkedin' | 'youtube' | 'twitter' | 'threads' | 'pinterest': Platform identifier
      - `profile_id` string: ID of the connected profile this platform entry was posted to
      - `profile_name` string: Display name of the connected profile
      - `status` string: Platform posting status: processing, published, failed, pending_deletion, deleted
      - `params` object, nullable: Platform-specific parameters used for this post
      - `error` string, nullable: Error summary (null on success)
      - `error_details` PostErrorDetails: Structured platform error details.
        - `platform_error_code` string, nullable: Error code returned by the platform API
        - `platform_error_subcode` string, nullable: Error subcode returned by the platform API
        - `platform_error_message` string, nullable: Error message returned by the platform API
        - `postproxy_note` string, nullable: Additional context from Postproxy about the error
      - `attempted_at` string, date-time, nullable: ISO 8601 timestamp of posting attempt
      - `permalink` string, nullable: Direct URL to the published post on the platform. Null if not published or permalink is unavailable
      - `insights` object: Engagement metrics (when available)
        - `impressions` integer: Number of impressions/views
        - `on` string, date-time: ISO 8601 timestamp when insights were captured
      - `attachments` PostPlatformAttachment[]: Platform-level files such as the video cover. Only returned by GET /posts/{id}, and omitted when there are none. For imported posts the cover comes from the platform (Instagram Reels, TikTok and LinkedIn videos). Imported TikTok posts have an empty media array, so use the cover as the thumbnail.
        - `id` string: Unique attachment identifier
        - `type` 'cover': Attachment type
        - `status` 'pending' | 'processed' | 'failed': Processing status
        - `content_type` string, nullable: MIME type of the file (e.g. image/jpeg)
        - `url` string, nullable: Hosted URL of the processed file (null until processed)

## Other responses

- `400`: Missing required parameters.
- `401`: Invalid, missing, or insufficient API key permissions.
- `422`: Validation failed.

---

[API](https://skmtc.dev/postproxy/apis/postproxy-social-media-api.md) - [All operations](https://skmtc.dev/postproxy/apis/postproxy-social-media-api/llms.txt) - [OpenAPI document](https://skmtc.dev/postproxy/apis/postproxy-social-media-api/revisions/d54482ac4ce7?raw)
